web-dev-qa-db-ja.com

Xcode 6とSwiftのビュー間のスナップチャットのようなスワイプナビゲーション)

Swipe Gesture Recognizerと埋め込みNavigation Controllerを使用して、アプリ内のView Controller間にスワイプナビゲーションを実装しようとしましたが、Snapchatのナビゲーションには見えません。

そのような機能を実装するための最も効率的で適切な方法は何でしょうか?

私はSwiftとプログラミングの初心者です。本当に役立つコメントがあれば感謝します。

17
maxster256

短いバージョンでは、コンテナビューコントローラを使用して、コントローラ内にスクロールビューを作成します。次に、アプリケーションで必要な画面ごとに個別のView Controllerを作成し、それらのView Controllerの親をコンテナView Controllerにします。

サンプルコードが記載されたgithubリポジトリ here があります。

20
lbrendanl

Pageviewcontrollerが必要です。これはもともとチュートリアルやコンテンツを表示するためのものでしたが、View Controllerをそこに配置することもできます。そこにはたくさんのチュートリアルがあり、基本的には、次に表示するView Controllerをプログラムに伝えるために少しロジックを適用する必要があります。

これは非常に高度な例ですが、次の場合に役立ちます。

https://github.com/cwRichardKim/RKSwipeBetweenViewControllers

8
cwRichardKim

Lbrendanlは制約を使用しないため、lbrendanlが提供するバージョンは好きではありません。思い通りにカスタマイズすることはできません。同じバージョンですが、制約があります:

scrollViewは、コントローラーのビューの両側に0の定数を持つ4つの制約を持つコントローラーに固定されたIBOutletです。

contentViewは、左右に0の定数を持つ4つの制約を持つscrollViewに固定されたscrollViewのサブビューとして追加されるIBOutletです。また、高さの等しい制約と幅の等しい制約もあります。幅の等しい制約は実行時に削除され、IBを落ち着かせます。このビューは、scrollViewのcontentViewを表します。

iOS 9の更新

 func setupDetailViewControllers() {
    var previousController: UIViewController?
    for controller in self.controllers {
        addChildViewController(controller)
        addControllerInContentView(controller, previousController: previousController)
        controller.didMoveToParentViewController(self)
        previousController = controller
    }
}

func addControllerInContentView(controller: UIViewController, previousController: UIViewController?) {
    contentView.addSubview(controller.view)
    controller.view.translatesAutoresizingMaskIntoConstraints = false

    // top
    controller.view.topAnchor.constraintEqualToAnchor(contentView.topAnchor).active = true

    // bottom
    controller.view.bottomAnchor.constraintEqualToAnchor(contentView.bottomAnchor).active = true

    // trailing
    trailingContentViewConstraint?.active = false
    trailingContentViewConstraint = controller.view.trailingAnchor.constraintEqualToAnchor(contentView.trailingAnchor)
    trailingContentViewConstraint?.active = true

    // leading
    let leadingAnchor = previousController?.view.trailingAnchor ?? contentView.leadingAnchor
    controller.view.leadingAnchor.constraintEqualToAnchor(leadingAnchor).active = true

    // width
    controller.view.widthAnchor.constraintEqualToAnchor(scrollView.widthAnchor).active = true
}

前の回答

    class ContainerViewController: UIViewController {

    @IBOutlet var scrollView: UIScrollView!
    @IBOutlet var contentView: UIView!

    // A strong reference to the width contraint of the contentView
    var contentViewConstraint: NSLayoutConstraint!

    // A computed version of this reference
    var computedContentViewConstraint: NSLayoutConstraint {
        return NSLayoutConstraint(item: contentView, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: scrollView, attribute: .Width, multiplier: CGFloat(controllers.count + 1), constant: 0)
    }

    // The list of controllers currently present in the scrollView
    var controllers = [UIViewController]()

    override func viewDidLoad() {
        super.viewDidLoad()

        initScrollView()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()

    }

    func initScrollView(){
        contentView.setTranslatesAutoresizingMaskIntoConstraints(false)

        contentViewConstraint = computedContentViewConstraint
        view.addConstraint(contentViewConstraint)

        // Adding all the controllers you want in the scrollView
        let controller1 = storyboard!.instantiateViewControllerWithIdentifier("AStoryboardID") as! AnUIControllerViewSubclass
        addToScrollViewNewController(controller)
        let controller2 = storyboard!.instantiateViewControllerWithIdentifier("AnotherStoryboardID") as! AnotherUIControllerViewSubclass
        addToScrollViewNewController(controller2)
    }

    // The main method, adds the controller in the scrollView at the left of the previous controller added
    func addToScrollViewNewController(controller: UIViewController) {
        self.addChildViewController(controller)

        contentView.addSubview(controller.view)

        controller.view.setTranslatesAutoresizingMaskIntoConstraints(false)

        // Setting all the constraints 
        let bottomConstraint = NSLayoutConstraint(item: contentView, attribute: .Bottom, relatedBy: .Equal, toItem: controller.view, attribute: .Bottom, multiplier: 1.0, constant: 0)

        let topConstraint = NSLayoutConstraint(item: contentView, attribute: .Top, relatedBy: .Equal, toItem: controller.view, attribute: .Top, multiplier: 1.0, constant: 0)

        let widthConstraint = NSLayoutConstraint(item: controller.view, attribute: .Width, relatedBy: .Equal, toItem: scrollView, attribute: .Width, multiplier: 1.0, constant: 0)

        var trailingConstraint: NSLayoutConstraint!
        if controllers.isEmpty {
            // Since it's the first one, the trailing constraint is from the controller view to the contentView
            trailingConstraint = NSLayoutConstraint(item: contentView, attribute: .Trailing, relatedBy: .Equal, toItem: controller.view, attribute: .Trailing, multiplier: 1.0, constant: 0)
        }
        else {
            trailingConstraint = NSLayoutConstraint(item: controllers.last!.view, attribute: .Leading, relatedBy: .Equal, toItem: controller.view, attribute: .Trailing, multiplier: 1.0, constant: 0)
        }

        // Setting the new width constraint of the contentView
        view.removeConstraint(contentViewConstraint)
        contentViewConstraint = computedContentViewConstraint

        // Adding all the constraints to the view hierarchy
        view.addConstraint(contentViewConstraint)
        contentView.addConstraints([bottomConstraint, topConstraint, trailingConstraint])
        scrollView.addConstraints([widthConstraint])

        controller.didMoveToParentViewController(self)

        // Finally adding the controller in the list of controllers
        controllers.append(controller)
    }  
}

私は過去にlbrendanlのバージョンを使用しました。今、私はこれを好む。あなたがそれについてどう思うか教えてください。

4
GaétanZ

UIPageViewControllerを使用し、これらのメソッドを削除してドットバーを非表示にすることをお勧めします。

presentationCountForPageViewController
presentationIndexForPageViewController

ここに良いチュートリアルがあります:

https://www.youtube.com/watch?v=8bltsDG2ENQ

これの素晴らしいレポは次のとおりです。

https://github.com/goktugyil/EZSwipeController

3
Esqarrouth

最初はPageControllerで実装されていた同様の要件がありましたが、後で各セルがフルスクリーンでスクロールが水平に設定されているUICollectionViewに変更しました。

1
zgorawski

Snapchatの場合、PageViewControllerではなく、Paged Scroll View。

1
user3871275

CATransitionを使用してスワイプアニメーションを作成してみてください。あるビューから別のビューにスワイプする方法の例を次に示します。

    UIView *parentView = [self.view superview];

CATransition *animation = [CATransition animation];
[animation setDuration:0.25];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromLeft];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];

[parentView addSubview:yourSecondViewController.view];
[self.view removeFromSuperview];

[[theParentView layer] addAnimation:animation forKey:@"showSecondViewController"];

私はここでそのコードのいくつかを見つけました: どうすればビュー間でスワイプ/スライドアニメーションを実装できますか?

0