iOS中简单动态布局入门(Xcode 6/Swift)

iOS中简单动态布局入门(Xcode 6/Swift),ios,swift,uikit,interface-builder,xcode6,Ios,Swift,Uikit,Interface Builder,Xcode6,我正在做我的第一个iOS应用程序,我对大小和布局的工作方式有点困惑(或者,在我的情况下,没有)。我觉得我正在尝试做的是(或者应该是)非常简单的,但是我尝试的每件事都没有达到预期的效果 在初始视图控制器中,我有一个UIScrollView: var frame = scrollView.bounds frame.origin.x = 0.0 frame.origin.y = 0.0 let view = pages[page] // pages[page] is U

我正在做我的第一个iOS应用程序,我对大小和布局的工作方式有点困惑(或者,在我的情况下,没有)。我觉得我正在尝试做的是(或者应该是)非常简单的,但是我尝试的每件事都没有达到预期的效果

在初始视图控制器中,我有一个
UIScrollView

var frame = scrollView.bounds
frame.origin.x = 0.0
frame.origin.y = 0.0

let view = pages[page]                // pages[page] is UIView loaded from XIB
view.contentMode = .ScaleAspectFit
view.frame = frame
scrollView.addSubview(view)

以编程方式,我使用
.addSubView
,添加从XIB加载的子视图:

var frame = scrollView.bounds
frame.origin.x = 0.0
frame.origin.y = 0.0

let view = pages[page]                // pages[page] is UIView loaded from XIB
view.contentMode = .ScaleAspectFit
view.frame = frame
scrollView.addSubview(view)
现在我们来看XIB(我将视图从“推断”更改为“自由形式”大小,只是为了拍摄此屏幕截图):

其中三个角上有标签,我希望它们对齐,使它们始终保持在这些角上,居中文本保持居中。但是,当我运行它时,事物被放置在它们原来的无聊位置(我添加了一个背景以便您可以看到问题):

我尝试过的(未成功):

  • 使用约束来定位元素(似乎没有任何作用,这让我相信问题在于子视图的大小
  • 设置子视图的各种大小和布局属性
我的最后期限很紧,所以我倾向于采用一种不太复杂的方式,但最终我希望有坚实的基础,真正了解这里发生了什么。我的问题是多部分(但相关):

  • 鉴于我缺乏经验,约束是否是定位视图元素的最佳方式,以便它们左对齐、右对齐、居中对齐等
  • 要使子视图在
    UIScrollView
    中的大小正确,我需要做什么
  • 如果屏幕方向改变,我需要做什么特殊的重新布局吗
任何建议都会很有帮助:具体的技术、教程、适当的文档(我一直在阅读文档,但这是一片大森林,我感到有点迷茫)


这是一个机会,让你们当中的一位iOS奇才有一个精彩的答案!

我想这个问题的答案可能会帮助你-


“contentView和它的superview(scrollView)之间的约束是scrollView的contentSize,而不是它的框架”

这里是一些示例代码。我在情节提要中添加了一个滚动视图,并对其大小和位置添加了约束(固定在左侧和右侧,垂直居中,固定高度为200)。我创建了两个包含视图的xib文件,每个文件都有4个角标签,其中一个位于中心。中心的文件有centerX和centerY约束,而角的文件都有到最近两条边的约束。我在xib中创建了200个高点的视图,以便在将它们添加到滚动视图时可以看到布局的样子,但没有必要这样做;我将添加的约束将适当调整视图的大小

class ViewController: UIViewController {

    @IBOutlet weak var scrollView: UIScrollView!
    override func viewDidLoad() {
        super.viewDidLoad()

        let firstSubview = NSBundle.mainBundle().loadNibNamed("View", owner: self, options: nil).first as UIView
        firstSubview.setTranslatesAutoresizingMaskIntoConstraints(false)
        scrollView.addSubview(firstSubview)

        let secondSubview = NSBundle.mainBundle().loadNibNamed("View2", owner: self, options: nil).first as UIView
        secondSubview.setTranslatesAutoresizingMaskIntoConstraints(false)
        scrollView.addSubview(secondSubview)
        scrollView.pagingEnabled = true

        let scrollViewHeight = scrollView.frame.size.height

        let viewsDict = ["first": firstSubview, "second": secondSubview]

        scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("|[first(vw)][second(vw)]|", options: nil, metrics: ["vw":scrollView.frame.size.width], views: viewsDict))
        scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[first(svh)]|", options: nil, metrics: ["svh": scrollViewHeight], views: viewsDict))
        scrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[second(svh)]|", options: nil, metrics: ["svh": scrollViewHeight], views: viewsDict))


    }

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
        println("scroll view size is: \(scrollView.frame.size)")
        println("scroll view contentSize is: \(scrollView.contentSize)")
    }

}
您会注意到,如果将第一个(水平)约束的格式字符串设置为普通视图,则会导致错误:“|[first(vw)][second(vw)]|”在这里,vw在度量中定义为scrollView.frame.size.width,因此我添加了两个与滚动视图宽度相同的视图,但将它们固定在侧边上。这在滚动视图中有效,因为这些侧边(由“|”字符表示)是到contentView的,而不是滚动视图本身。因此,这些约束导致contentView的宽度是滚动视图的两倍(因此您无需自己明确设置)。登录ViewDidDisplay会提供以下信息

scroll view size is: (320.0,200.0)
scroll view contentSize is: (664.0,200.0)

1、是的,约束是你的子视图的位置和大小的最佳方法。2。你也应该使用约束来调整你的子视图。3。如果你仍然希望你的标签在角落里并且像你的图像一样在中间居中,那么不,你不需要在旋转上做任何事情。滚动视图本身也应该对它的超视界有约束。你可以更详细地解释一下你想要完成什么?你有多个子视图要添加吗?它们是否仅在一个维度上比滚动视图大(因此只有水平或垂直滚动)?嗯…我从中学到了很多,谢谢!但是,我不认为这正是我想要的…特别是,我不想为滚动视图的每个视图添加约束。也就是说,我想说“滚动视图的每个子视图都应该占据其整个高度和指定的宽度”。然后,每个子视图都会根据其约束条件进行布局……谢谢你,Ash,我想这是我问题的核心所在!