web-dev-qa-db-ja.com

Swiftスーパービューからサブビューを削除する

私はscrollViewを持っていて、それにrefreshcontrollを追加しました。

self.refreshControl = UIRefreshControl()
self.refreshControl.attributedTitle = NSAttributedString(string: "Frissítéshez húzzad! :)")
self.refreshControl.addTarget(self, action: "refresh:", forControlEvents: UIControlEvents.ValueChanged)
self.scrollView.addSubview(refreshControl)

refreshメソッドでは、scrollviewからすべてのサブビューを削除してから、scrollviewを再設定する必要があります。

self.refreshControl = UIRefreshControl()
self.refreshControl.attributedTitle = NSAttributedString(string: "Frissítéshez húzzad! :)")
self.refreshControl.addTarget(self, action: "refresh:", forControlEvents: UIControlEvents.ValueChanged)
self.scrollView.addSubview(refreshControl)

プルしようとすると、scrollviewは新しいデータを取得しますが、refreshcontrollがありません。スクロールビューからサブビューを削除すると、refreshcontrollも削除されるためだと思います。 (refreshメソッドにrefreshcontrollを再度追加すると、scrollviewにrefreshconrollが再び表示されます)しかし、別の問題があります。下に移動するスクロールビューを更新した後..私は写真に添付しました:

これは私がsubiewsを削除する方法です:

func refresh(sender:AnyObject)
{
    //remove all subviews from scrollview..
    let subViews = self.scrollView.subviews
    for subview in subViews{
        println("for removing...")
        subview.removeFromSuperview()
    }

    println("refresh called..")
    UIApplication.sharedApplication().applicationIconBadgeNumber = 0
    //remove all elements from the array
    tstFrames.removeAll(keepCapacity: false)
    //refresh data from webservice and adding it to tstFrames Array
    wsServiceFeedTst()
    //adding items to the scrollview from tstFramesArray
    addPosts()
    self.refreshControl.endRefreshing()

}

更新前のスクロールビューは次のようになります。 enter image description here

これは、更新後の外観です。 enter image description here

なぜこれが下がっているのか誰かが私を助けることができますか?

ありがとうございました!

ありがとう、これが解決策です:

let subViews = self.scrollView.subviews
for subview in subViews{
    println("for removing...")
    if (subview is PostLineItem) {
        subview.removeFromSuperview()
    }
    else {
        println("not removing..")
    }
}
7
solarenqu

すべてのサブビューを削除することで、ビューの更新やレイアウトの制約など、明示的に追加したもの以外のサブビューを削除することもできます。

(そしてコメントからあなたの質問に答えるために、レイアウト制約は実際にはサブビューである可能性があります。レイアウト制約を除くすべてのサブビューを削除する方法をここで説明します: https://stackoverflow.com/a/27281242/2274694 。)

一般に、追加したビューのみが削除されるように、コードをより具体的に変更することをお勧めします。たとえば、addPostsメソッドで追加するサブビューにタグを追加できます。

post.tag = 1000

次に、refresh:でそのタグが付いたサブビューのみを削除します。

let subViews = self.scrollView.subviews
for subview in subViews{
    if subview.tag == 1000 {
        subview.removeFromSuperview()
    }
}

自分で明示的に追加していないサブビューを削除しないようにするため。

編集:OPの追加されたサブビューはすべてカスタムタイプPostLineItemであることが判明したため、代わりにすべてのPostLineItemsを削除できるため、タグは不要です。

for subview in self.view.subviews {
    if subview is PostLineItem {
        subview.removeFromSuperview()
     }
}
15
Lyndsey Scott

私は今日もこの問題に遭遇し、私の解決策を共有したいと思います。 Swiftの次のUIView拡張機能を使用して、ビューのすべてのサブビュー(およびそれらのサブビュー)を削除できます。さらに、すべての制約を同じ方法で削除するためのソリューションを添付しました。

extension UIView {

  // Recursive remove subviews and constraints
  func removeSubviews() {
    self.subviews.forEach({
        if !($0 is UILayoutSupport) {
            $0.removeSubviews()
            $0.removeFromSuperview()
        }
    })

  }

  // Recursive remove subviews and constraints
  func removeSubviewsAndConstraints() {
    self.subviews.forEach({
        $0.removeSubviewsAndConstraints()
        $0.removeConstraints($0.constraints)
        $0.removeFromSuperview()
    })
  }

}

最初の解決策はすべての制約を維持します。Lyndseysの回答を参照してください。このソリューションでは、UIViewの下の階層全体が削除されることに注意してください。特定のサブビューを削除するだけの場合は、次のように交換または拡張します。

if !($0 is UILayoutSupport) && !($0 is PostLineItem)
3
masp