2017-05-09 9 views
1

私はポイントに右に行くでしょう。スクロール/サイズ変更UITableView

私は2つのサブビューを持つUIViewControllerを持っています。一番上のもの(今からHeaderViewと呼ぶ)はカスタムUIViewであり、一番下のものはUITableViewです。
HeaderViewが左上、右上から0マージンを持ち、さらに固定高さになるようにInterfaceBuilderでそれらを設定しました。 UITableViewはすべての側から0マージンですぐ下にあります。

私の目標は、UITableViewのコンテンツのスクロールを開始するときに、HeaderViewが縮小を開始し、スクロールせずにUITableViewが高くなるような動作を達成することです。これは、HeaderViewが最小の高さに達するまで続く必要があります。その後、UITableViewは通常どおりスクロールを開始する必要があります。下にスクロールするとき、エフェクトを元に戻す必要があります。

私は最初、UITableViewの代わりにUIScrollViewを使用してこれを開始しました。希望の結果が得られました。コントローラのviewDidLoad()方法 self.scrollView.delegate = self にUIScrollViewDelegateを設定し、プロトコル

  • に適合するのUIViewControllerを宣言し
    @IBOutlet weak var scrollView: UIScrollView!

  • コンセントにUIScrollViewのを接続

    1. :ここではどのようにありますUIScrollViewがスクロールするときの代行受信:
      adjustScrolling(offset:scrollView:)方法で

    2. 「魔法」

    は、今度は、この方法では何が起こるか見てみましょう起こります。

    private func adjustScrolling(offset: CGFloat, scrollView: UIScrollView) { 
    
         // bind value between 0 and max header scroll 
         let actualOffset: CGFloat = offset < 0 ? 0 : (offset >= self.maxHeaderScroll ? self.maxHeaderScroll : offset) 
    
         // avoid useless calculations 
         if (actualOffset == self.currentOffset) { 
          return 
         } 
    
         /** 
         * Apply the vertical scrolling to the header 
         */ 
         // Translate the header up to give more space to the scrollView 
         let headerTransform = CATransform3DTranslate(CATransform3DIdentity, 0, -(actualOffset), 0) 
         self.header.layer.transform = headerTransform 
         // Adjust header's subviews to new size 
         self.header.didScrollBy(actualOffset) 
    
         /** 
         * Apply the corrected vertical scrolling to the scrollView 
         */ 
         // Resize the scrollView to fill all empty space 
         let newScrollViewY = self.header.frame.origin.y + self.header.frame.height 
         scrollView.frame = CGRect(
          x: 0, 
          y: newScrollViewY, 
          width: scrollView.frame.width, 
          height: scrollView.frame.height + (scrollView.frame.origin.y - newScrollViewY) 
         ) 
         // Translate the scrollView's content view down to contrast scrolling 
         let scrollTransform = CATransform3DTranslate(CATransform3DIdentity, 0, (actualOffset), 0) 
         scrollView.subviews[0].layer.transform = scrollTransform 
         // Set bottom inset to show content hidden by translation 
         scrollView.contentInset = UIEdgeInsets(
          top: 0, 
          left: 0, 
          bottom: actualOffset, 
          right: 0 
         ) 
    
         self.currentOffset = actualOffset 
        } 
    

    私が何かを忘れていないなら、これは望ましい効果を達成するのに十分であるはずです。私はそれを打破してみましょう:

    1. 私はactualOffsetことを確認した場合、私は
    2. (私は、それが動的に計算だと思うが、これは本当に重要ではありません)actualOffsetがちょうど67である0とself.MaxHeaderScrollの間に結合計算この関数が最後に呼び出されて以来変更されていません。変更を加えるのは気にしません。これにより、無駄な計算が回避されます。
    3. ヘッダーにスクロールを適用するには、CATransform3DTranslateをy軸だけに適用して、actualOffsetというように変換します。
    4. 私はself.header.didScrollBy(actualOffset)を呼び出して、HeaderViewで内部的に視覚的な変更を適用できるようにします。しかし、これは問題を隠すことはありません。
    5. scrollViewのサイズを変更して、HeaderViewが上位になったので、上下から0の余白を維持します。
    6. 私はスクロールビューのコンテンツをスクロールと対照的に同じactualOffset分だけ翻訳します。この作品は、私が達成したい正しい視覚効果に不可欠です。私がこれをしなかった場合、scrollViewはまだ正しくサイズ変更されますが、コンテンツはすぐにスクロールを開始しますが、これは望ましくありません。HeaderViewが最小の高さに達すると、スクロールが開始されます。
    7. scrollviewに下の挿入図を設定して、最後までスクロールできるようになりました。これがなければ、scrollView自体がコンテンツの終わりに達したと思うので、scrollViewの最後の部分が途切れることになります。
    8. は、最後に私が後で比較

    私が言ったように、これは正常に動作するためにactualOffsetを格納します。この問題は、UIScrollViewからUITableViewに切り替えるときに発生します。私は、UITableViewがUIScrollViewから継承して以来、動作すると仮定しました。
    数字の6のコードはうまくいきません。何がうまくいかないのか分かりませんので、私が見つけたものや気づいたもののすべてをリストにします。うまくいけば誰かが私を助けることができるだろう。

    • UIScrollViewの場合、ポイント6では、scrollView.subviews[0]は、その中のすべてのコンテンツを保持するビューを参照します。私がUITableViewに変更すると、このサブビューは、UITableViewWrapperViewのようなもので、どのドキュメントも見つからなかったようです。また、XCodeはそれを有効なクラスとして認識しません。これはすでにイライラしています。
    • もし私がポイント6であれば、私はx軸上で何らかの翻訳をしています(50としましょう)。すぐに0に戻される初期の非常に速い翻訳を見ることができます。これはUITableViewがスクロールを開始し、スクロール中は動きません。
    • 希望の結果を得るために、ポイント6のサブビューのフレームを変更しようとしました。スクロールが正しくても、UITableViewをスクロールするとトップセルが消えていきます。私はこれを薄くしています。私はdequeueReusableCell(withIdentifier:for:)を使って細胞を分化させています。そして、実際には上の細胞は見えないとUITableViewは考えています。私はこの問題を回避することができませんでした。
    • self.tableView.tableHeaderViewのUIViewをactualOffsetという高さに設定してみましたが、スクロールとは対照的ですが、これはセルが正しくスクロールできない不思議な効果をもたらし、UITableViewが初期位置に戻ったときにギャップがあります上。これについての手掛かりもありません。

    ここにはたくさんの情報がありますので、もっと詳しくお気軽にお問い合わせください。前もって感謝します。

  • +0

    ただデモを作る – SeanLintern88

    +0

    @ SeanLintern88は運がいいですか? –

    +0

    ねえ、私はデモを作ったが、その後あなたの質問を再読し、すべてをカバーしているかどうかわからない、デモを見てください – SeanLintern88

    答えて

    6

    私は最近、このようなものを作ったので、私はそれを達成しHERESにする方法:

    は、高さ制約定数とのUIViewを作成して、ビュー/ VCにこれをリンクして、あなたは後ろのVCのビューフルスクリーンに制約のUITableViewていますUIView。

    UITableViews contentInset topを 'headerView'の開始高さに設定しました。scrollViewDidScrollでは、ヘッダーの高さが最小になるまで定数を調整します。

    Here is a demo

    あなたはそれを実行した場合、青色の部分は、あなたの「ヘッダー」で、色付きの行は、単に任意のセルです。あなたは青い領域で必要なものを自動レイアウトすることができます。それは自動サイズとすべてが必要です

    +0

    ちょっと男、私はあなたの例のおかげで働くことができた。うーん、私はあなたに1つ借りている! –

    +0

    StackOverflowで私に賞金をもらえるようになるとすぐに –

    +0

    targetContentOffsetを実装するときにバーターを取得します。別のscrollViewDelegateメソッドは、最小/最大高さの間で終了するスクロールアニメーションを停止できます。必要 – SeanLintern88

    関連する問題