Pan Segue 调用 viewDidLoad 循环

Pan Segue Calls viewDidLoad Loop

我的平移手势以编程方式伪造按钮按下。如果您按下实际按钮,VC 的 viewDidLoad 会再次运行一次,然后停止,一切正常。 但是 当我使用平移手势以编程方式伪造按钮按下时,viewDidLoad 运行大约七次,然后停止。

右边缘手势会触发 "tomorrow" 状态,该状态会加载几次。此时,左边缘手势会触发 "today" 状态。这也加载了 4-5 次。

有什么想法吗?如果需要,下面的一些代码。

在 viewDidLoad 中添加了平移手势:

    //Adds edge gesture depending on VC state
    if curMainList == "Today" {
        let panLeftEdgeGesture_MainVC = UIScreenEdgePanGestureRecognizer(target: self, action: "panLeftEdge_toLifeList:")
        panLeftEdgeGesture_MainVC.edges = .Left
        view.addGestureRecognizer(panLeftEdgeGesture_MainVC)

        let panRightEdgeGesture_MainVC = UIScreenEdgePanGestureRecognizer(target: self, action: "panFromRightEdgeAction:")
        panRightEdgeGesture_MainVC.edges = .Right
        view.addGestureRecognizer(panRightEdgeGesture_MainVC)

        self.footer_LeftBtn.addTarget(self, action: "LeftFooterBtnPress", forControlEvents: UIControlEvents.TouchUpInside)
    }
    else {
        let panLeftEdgeGesture = UIScreenEdgePanGestureRecognizer(target: self, action: "panFromLeftEdgeAction:")
        panLeftEdgeGesture.edges = .Left
        view.addGestureRecognizer(panLeftEdgeGesture)
    }

手势触发:

//Gestures visible when view is 'Today'
func panLeftEdge_toLifeList(sender: UIScreenEdgePanGestureRecognizer) {
    dispatch_async(dispatch_get_main_queue()) { () -> Void in
        self.performSegueWithIdentifier("segueToLifeLists", sender: nil)
    }
}

func panFromRightEdgeAction(sender: UIScreenEdgePanGestureRecognizer) {
    //self.tomHdrBtnPress(tomorrowHdr)
    tomorrowHdr.sendActionsForControlEvents(UIControlEvents.TouchUpInside)
}

//Gesture added when viewing 'Tomorrow' list
func panFromLeftEdgeAction(sender: UIScreenEdgePanGestureRecognizer) {
    //self.todayHdrBtnPress(todayHdr)
    todayHdr.sendActionsForControlEvents(UIControlEvents.TouchUpInside)
}

@IBAction func todayHdrBtnPress(sender: AnyObject) {
    UIView.animateWithDuration(0.75, animations: {
        //Header changes
        self.hdrBox.backgroundColor = UIColor(red: 46/255.0, green: 173/255.0, blue: 11/255.0, alpha: 1.0)
        self.footer_RightArrow.hidden = false
        self.footer_RightBtn.hidden = false
        }
        , completion: nil
    )
    curMainList = "TodayTask"
    currentListEntity = curMainList
    viewDidLoad()
}

@IBAction func tomHdrBtnPress(sender: AnyObject) {
    UIView.animateWithDuration(0.75, animations: {
        //Header changes
        self.hdrBox.backgroundColor = UIColor(red: 49/255.0, green: 82/255.0, blue: 171/255.0, alpha: 1.0)
        self.footer_LeftBtn.addTarget(self, action: "LeftFooterBtnPress", forControlEvents: UIControlEvents.TouchUpInside)
        }
        , completion: nil
    )
    curMainList = "TomTask"
    currentListEntity = curMainList
    viewDidLoad()
}

问题在于平移手势是连续手势(意味着当您移动手指时,会重复调用处理程序)。对于平移手势,它被调用一次 gesture.state .Began,当用户的手指移动时用 state 重复 .Changed,最后用 state.Ended.Cancelled 当用户停止手势时。

因此,您通常不会通过连续手势触发 animateWithDuration。您只需根据 gesture.translationInView() 或您拥有的内容更新状态。只需立即更新视图以反映更新后的平移,它被如此频繁地调用,以至于它最终渲染了一些感觉像动画的东西,但它实际上只是一系列更新 linked 以连续更新你的手势识别器的处理程序随着用户手势的进展而接收。

唯一一次在连续手势中设置动画是在 .Ended.Cancelled 时完成动画。例如,也许用户将他们的手指拖到一半,所以在 .Changed 上你只是立即更新视图而没有任何动画,但是当他们抬起他们的手指时(即手势处理程序接收 .Ended),你可能会动画完成视图的最终状态。

最重要的是,手势识别器中的处理是一种非常不同的动画机制,它可能由按钮产生(在其中您调用 animateWithDuration 方法一次以启动 UIKit 的动画然后照顾你)。最好不要将 updating/animating 和 UI 这两种截然不同的方式混为一谈。


您还在您的一个 pan 处理程序中执行 segue。如果你想在平移时交互式地执行 segue,你应该参考 WWDC 2013 视频 Custom Transitions Using View Controllers,它展示了如何将动画控制器(它决定动画的性质)与交互控制器(它links 手势与动画控制器的进度)。但是在这个模式中,你只执行一次 segue,并且只更新手势中的 UIPercentDrivenInteractiveTransition,这将 link 用户手指的转换进度。 `