我正在尝试向scrollView显示简单的自定义视图。这是我的代码:
struct scrollViewDataStruct {
let title: String?
let image: UIImage?
}
class ViewController: UIViewController {
@IBOutlet weak var scrollView: UIScrollView!
var scrollViewData = [scrollViewDataStruct]()
override func viewDidLoad() {
super.viewDidLoad()
scrollViewData = [
scrollViewDataStruct(title: "First", image: #imageLiteral(resourceName: "iPhone 8 Copy 2")),
scrollViewDataStruct(title: "Second", image: #imageLiteral(resourceName: "iPhone 8 Copy 3"))
]
self.scrollView.backgroundColor = .yellow
scrollView.contentSize.width = self.scrollView.frame.width * CGFloat(scrollViewData.count)
var i = 0
for _ in scrollViewData {
let view = CustomView(frame: CGRect(x: self.scrollView.frame.width * CGFloat(i), y: 0, width: scrollView.frame.width, height: self.scrollView.frame.height))
self.scrollView.addSubview(view)
i += 1
}
// Do any additional setup after loading the view, typically from a nib.
}
}
class CustomView: UIView {
let imageView: UIImageView = {
let imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.backgroundColor = UIColor.blue
return imageView
}()
override init(frame: CGRect) {
super.init(frame: frame)
self.addSubview(imageView)
imageView.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
imageView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
imageView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
imageView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
正如您所见,CustomView's frame = scrollView's frame
但是当我运行应用程序时,它并不像我预期的那样:
然后,在故事板中,我将设备从iphone8更改为iphone 8 plus并再次运行。它正确显示CustomView
。我不知道,scrollView
始终是正确的,但CustomView
不是。
有什么建议?
答案 0 :(得分:0)
在viewDidLoad中,UI组件将假设您具有在故事板中所采用的大小。
有两种方法可以做到这一点:
<强> 1。使用autoresizingMask
属性
autoresizingMask属性将调整视图大小,如果其containerView的框架已更改
var i = 0
for _ in scrollViewData {
let view = CustomView(frame: CGRect(x: self.scrollView.frame.width * CGFloat(i), y: 0, width: scrollView.frame.width, height: self.scrollView.frame.height))
view.autoresizingMask = .flexibleHeight
self.scrollView.addSubview(view)
i += 1
}
<强> 2。使用固定参数,例如UIScreen.main.bounds.size.height
只需参考屏幕高度而不是滚动视图的高度来更新自定义视图高度的代码。它会正常工作
var i = 0
let height = UIScreen.main.bounds.size.height
for _ in scrollViewData {
let view = CustomView(frame: CGRect(x: self.scrollView.frame.width * CGFloat(i), y: 0, width: scrollView.frame.width, height: height))
self.scrollView.addSubview(view)
i += 1
}
答案 1 :(得分:0)
您的问题是您在自动布局运行之前访问了scrollView的frame
,并确定了实际设备frame
的大小。快速解决方法是将您的设置代码移到viewDidLayoutSubviews
的覆盖中。
但是你必须要小心,因为与viewDidLoad
不同,viewDidLayoutSubviews
会运行多次,所以你必须确保多次不添加你的观点。
// property - have we set up the views yet?
var setup = false
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if !setup {
scrollView.contentSize.width = self.scrollView.frame.width * CGFloat(scrollViewData.count)
var i = 0
for _ in scrollViewData {
let view = CustomView(frame: CGRect(x: self.scrollView.frame.width * CGFloat(i), y: 0, width: scrollView.frame.width, height: self.scrollView.frame.height))
self.scrollView.addSubview(view)
i += 1
}
setup = true
}
}
您应该考虑使用约束将视图放在scrollView内容中而不是弄乱frame
计算,然后自动布局会自动做正确的事情。