更改背景图像时容器视图动画无法正常工作

时间:2015-04-17 04:49:13

标签: xcode swift uiview uiviewanimation uicontainerview

我在IB中有3个观看次数。 View One(1)有一个视图和一个UIImage,我用它作为这个ViewController的背景。视图二(2)(详细信息视图)和视图三(3)(选项视图)是容器视图,两者都放在彼此之上。我在视图2中有一个按钮,动画在左侧查看2并从右侧移动视图3。我可以从View 3向后移动到右边,从左侧重新启动View 2.

以下是我的文档大纲: enter image description here

白色BG,只是标题栏下的背景,以防万一有人想知道。

以下是我用来制作动画的代码:

func showOptions(){
    println("show options")

    optionsView.center.x = self.view.bounds.width + self.view.bounds.width / 2
    optionsView.hidden = false

    UIView.animateWithDuration(0.5, animations: {

        self.blurView.alpha = 1

        // slide containers around
        // println(self.view.bounds.width)

        self.detailsView.center.x = -self.view.bounds.width * 2
        self.optionsView.center.x = self.view.bounds.width / 2
    })
}
func showDetails(){
    println("show detials")

     optionsView.center.x = self.view.bounds.width / 2

    UIView.animateWithDuration(0.5, animations: {

        self.blurView.alpha = 0

        // slide containers around
        // println(self.view.bounds.width)

        self.detailsView.center.x = self.view.bounds.width / 2
        println("\(self.optionsView.center.x) this is center X value 1")

        self.optionsView.center.x = self.view.bounds.width * 2
        println("\(self.optionsView.center.x) this is center X value 2")

    }, completion: {
            (value: Bool) in
            println("\(self.optionsView.center.x) this is center X value 3")
    })
}

那些对我从打印陈述中得到什么感到好奇的人

当我没有尝试更改背景照片时,我应该这样做:

  • 160.0这是中心X值1
  • 640.0这是中心X值2
  • 640.0这是中心X值3

当我更换照片时,我得到了这些值:

  • 160.0这是中心X值1
  • 640.0这是中心X值2
  • 160.0这是中心X值3

当我尝试更改此视图控制器的背景视图图像时,什么不起作用。

let par3 = UIImage(named: "par3.png")
backgroundImage.image = par3
   // println("par three")
    showDetails()

当我更换背景照片时,View 2和View 3都会从左侧激活到屏幕上。我不知道为什么。当我切换背景照片时,是否与要修改的View Controller的宽度有关?

感谢您的帮助!

1 个答案:

答案 0 :(得分:4)

感觉你只有一半拥抱自动布局。您最初使用它来布置您的观看次数,但在您为视图设置动画时,您却不会使用它。您正在修改中心x位置,这是旧的动画制作方式。它有点工作,但是当我换掉背景图片时,我认为所有东西都会重置为你的初始约束,因为这会导致在引擎盖下调用layoutIfNeeded(),这会使用约束来定位一切都回到了最初的状态。

您需要更改修改约束的方法,而不是修改视图的中心x位置。这意味着即使你换掉图像,你的约束仍然是准确的,一切都应该按预期工作。这需要以特定方式设置约束,我将尝试并演示。

首先,我设置了一个带有几个子视图控制器的父视图控制器。每个孩子都有一个按钮,可以在父母中调用委托方法。

我的故事板看起来像这样:

storyboard setup

这是检查员的样子:

storyboard inspector

关于故事板设置的几点:

  • 我有一个主容器视图,它是父视图的子视图。此主容器视图的clipSubviews设置为YES,因此当我们向左和向右移动视图时,它们不会显示在主容器的边界之外。
  • 选项和详细信息容器视图都设置了约束以匹配主容器视图的宽度和高度。
  • 详细信息容器视图的左侧设置为右侧靠选项容器视图的右侧,即[options] [detail]。它们不是直接相互叠加的。
  • 详细信息容器视图具有约束条件,因此它的上边缘与选项容器视图的上边缘对齐。
  • 使用约束设置选项容器视图,以与主容器视图的左上角对齐。这与之前的2个子弹相结合意味着最初细节容器视图在屏幕右侧。我在父视图控制器中引用了一个约束,该约束将选项容器视图的左侧与mainContainerView的左侧(在上面的屏幕截图中选择的那个)排成一行,这就是我的意思用来动画一切。

这是父类的样子:

class ParentViewController: UIViewController, OptionsViewControllerDelegate, DetailViewControllerDelegate {

    struct Constants {
        static let optionsEmbedSegue = "optionsEmbedSegue"
        static let detailEmbedSegue = "detailEmbedSegue"
    }

    @IBOutlet weak var mainContainerView: UIView!

    @IBOutlet weak var optionsLeadingSpaceConstraint: NSLayoutConstraint!

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == Constants.optionsEmbedSegue {
            let childViewController = segue.destinationViewController as OptionsViewController
            childViewController.delegate = self
        } else if segue.identifier == Constants.detailEmbedSegue {
            let childViewController = segue.destinationViewController as DetailViewController
            childViewController.delegate = self
        }
    }

    func optionsViewControllerDidSelectToShowDetail(optionsViewController: OptionsViewController) {
        animateOptionsToNewXPosition(-CGRectGetWidth(mainContainerView.bounds))
    }

    func detailViewControllerDidSelectToGoBack(detailViewController: DetailViewController) {
        animateOptionsToNewXPosition(0)
    }

    func animateOptionsToNewXPosition(xPosition: CGFloat) {
        optionsLeadingSpaceConstraint.constant = xPosition

        UIView.animateWithDuration(0.5, animations: { () -> Void in
            self.mainContainerView.layoutIfNeeded()
        })
    }
}

如果您查看optionsViewControllerDidSelectToShowDetail方法,则会看到第animateOptionsToNewXPosition(-CGRectGetWidth(mainContainerView.bounds))行。这会将选项视图控制器移动到主容器视图宽度的左侧。这意味着它将消失在屏幕的左侧,并且由于所有其他约束,它将使用它拖动细节视图控制器,从而在mainContainerView中显示详细视图控制器。相反的情况发生在detailViewControllerDidSelectToGoBack方法中,只需将该约束中的常量设置回0,这会使选项视图控制器返回,并将detailViewController推向右侧。

我希望有所帮助。