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

标签 xcode swift uiview uiviewanimation uicontainerview

我在 IB 中有 3 个 View 。 View One(1) 有一个 View 和一个 UIImage,我将其用作此 ViewController 的背景。 View 二(2)(详细信息 View )和 View 三(3)(选项 View )是容器 View ,两者都放置在彼此之上。我在 View 2 中有一个按钮,它使 View 2 向左移动并从右侧移动 View 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

当我尝试更改此 View Controller 的背景 View 图像时不起作用。

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

当我更改背景照片时, View 2 和 View 3 都从左侧动画到屏幕上。我只是不确定为什么。是否与切换出背景图片时修改View Controller的宽度有关?

感谢您的帮助!

最佳答案

感觉您对自动布局只接受了一半。您最初使用它来布置您的 View ,但是当您为 View 设置动画时您没有使用它。您正在修改中心 x 位置,这是旧的动画方式。它有点工作,但后来我认为当你换出背景图像时,一切都被重置为你的初始约束,因为这会导致调用引擎盖下的 layoutIfNeeded(),它使用约束来将所有内容放回到最初的位置。

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

首先,我设置了一个带有几个 subview Controller 的父 View Controller 。每个子项都有一个按钮,可以调用父项中的委托(delegate)方法。

我的 Storyboard是这样的:

storyboard setup

这是检查员的样子:

storyboard inspector

关于 Storyboard设置的几点:

  • 我有一个主容器 View ,它是父 View 的 subview 。这个主容器 View 将 clipSubviews 设置为 YES,这样当我们左右移动 View 时,它们不会出现在主容器的边界之外。
  • 选项和详细容器 View 都设置了与主容器 View 的宽度和高度相匹配的约束。
  • 详细信息容器 View 的左侧设置为紧靠选项容器 View 的右侧,即 [options][detail]。它们并不直接重叠。
  • 详细容器 View 有一个约束,因此它的上边缘与选项容器 View 的上边缘对齐。
  • 选项容器 View 设置了约束,与主容器 View 的左上角对齐。这与前面的 2 个项目符号相结合意味着最初详细信息容器 View 位于屏幕右侧。我在父 View Controller 中引用了约束,该约束将选项容器 View 的左侧与 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)) 行。这是将选项 View Controller 向左移动主容器 View 的宽度。这意味着它会消失在屏幕的左侧,并且由于所有其他约束,它会拖动详细 View Controller ,在 mainContainerView 中显示详细 View Controller 。相反的情况发生在 detailViewControllerDidSelectToGoBack 方法中,只需将该约束中的常量设置回 0,这会将选项 View Controller 带回,并将 detailViewController 推到右侧。

希望对您有所帮助。

关于xcode - 更改背景图像时容器 View 动画无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29690569/

相关文章:

ios - 无法向 UIView 添加两个手势

objective-c - 如何为 Storyboard中的每个 View 分配名称

Swift:二叉树搜索,int 不在树中

ios - 重复淡入淡出效果不起作用

ios - ScrollView ios 8 Xcode 不滚动 - Swift

objective-c - 如何将 NSDictionary 转换为 Swift Dictionary<String, NSObject>?

ios - CNContactViewController - 更改取消和完成按钮的颜色

ios - 将 subview 添加到 tableViewController 中的主视图将 subview 添加到 TableView 而不是 swift 中的 View

ios - UIView 可以在 segue 过渡期间固定到位吗?

ios - 如何修复此 CopyPNG 文件错误?