如何为viewcontroller的视图有多个位置状态?

我想解决的问题是这样的:我有一个DetailViewController显示我的模型的数据与UIImageView的, UITextFields等。

如果用户点击一个button,这些DetailViewController的视图移动到不同的位置,并开始可编辑。 当可编辑的时候,如果用户点击一个UITextField (其中只有一个是特殊的),则UITextField移动到屏幕的顶部, UITableView自动完成它(就像在google上input内容一样)。

用户也可以点击相同的button返回到显示状态(没有任何可编辑的地方)。

所以基本上我有一个ViewController有3个可能的状态的视图: DisplayStateEditingStateEditingWithFocusOnSpecialTextFieldsState

我想要所有那些由NSLayoutConstraints描述的定位状态,如果可能的话,只是在故事板。

我可以做的一件事就是将这个Animate改为故事板的状态/位置 ,但是这涉及到为代码中的每个状态编写每个约束,因此在开发过程中,我无法在故事板上很好地描绘它们(另外,在代码中编写约束是很多的不如在故事板中可维护)。

我想要的是像创build3个不同的XIB,例如,或在Storyboard中的每个子视图的3个不同的位置,我的DetailViewController不同副本,然后在它们之间的animation。

如果它有什么不同,我总是使用最新的iOS版本(iOS 8现在)和Swift。 如果你不想在Swift中回答,我也很了解Objective-C。

据我所知,没有办法用三种不同的观点去做,得到你想要的结果(至less没有直接的方法)。 一种方法是为每个视图调整3个约束(每个状态一个约束)到超级视图的任何一个边缘(除了需要修改的其他约束之外)。 一个人会有一个高优先级(我使用900,不能是1000),其他2将有一个较低的优先级(在我的例子499)。 当您切换状态时,您将更改3中的哪个具有高优先级。 这确实涉及到很多约束,我发现在代码中实现切换的最简单方法是在IB中给出约束标识符(在Identity Inspector的“用户定义的运行时属性”部分中)。 这种方法意味着我不必为所有这些限制而制作IBOutlets。 以下是故事板中两个视图的示例,

在这里输入图像说明

你可以看到文本字段顶部有3个约束,图像视图有3个centerY约束(尽pipe你看不到有3个约束)。 每个约束(在3个组中)的标识符被设置为“显示”,“编辑”或“焦点”。 我给一个叫做“显示”的优先级为900,另外两个是499(因为我希望视图以显示模式启动)。 在这个testing应用程序中,我使用3个button来改变状态,但是,当然,您可以使用其他方法来实现。 这里是我用来切换优先级的代码,

 enum EditState: String { case Display = "display" // these strings are the same as the ones assigned to the identifier property of the constraints in IB (in "user defined runtime attributes") case Editing = "edit" case EditWithFocus = "focus" } class ViewController: UIViewController { @IBOutlet weak var imageView: UIImageView! func updatEditingState(state: EditState) { var constraintsArray = self.view.constraints() as [NSLayoutConstraint] constraintsArray += self.imageView.constraints() as [NSLayoutConstraint] for con in constraintsArray { if let name = con.identifier? { if name == "display" || name == "edit" || name == "focus" { con.priority = (name == state.rawValue) ? 900 : 499 } } } UIView.animateWithDuration(0.5) {self.view.layoutIfNeeded()} } @IBAction func EnterEditingState(sender: UIButton) { updatEditingState(EditState.Editing) } @IBAction func enterDisplayStatus(sender: UIButton) { updatEditingState(EditState.Display) } @IBAction func enterFocusStatus(sender: UIButton) { updatEditingState(EditState.EditWithFocus) } }