Ios 如何以编程方式使用自动布局在scrollview中水平放置N个视图?
我想在scrollview中水平创建N个视图。因此,我创建了一个临时视图,并将当前视图指定给该视图。然后我基于该视图放置约束。只有一个视图显示其他视图未显示。 我想要两个视图之间的水平空间。 我正在使用VFL设置自动布局。 这是我的代码Ios 如何以编程方式使用自动布局在scrollview中水平放置N个视图?,ios,ipad,autolayout,swift3,Ios,Ipad,Autolayout,Swift3,我想在scrollview中水平创建N个视图。因此,我创建了一个临时视图,并将当前视图指定给该视图。然后我基于该视图放置约束。只有一个视图显示其他视图未显示。 我想要两个视图之间的水平空间。 我正在使用VFL设置自动布局。 这是我的代码 func ect() { let scrollHeight = self.scrollObj.frame.size.height - 40 let scrollHeightString = String(describing: s
func ect() {
let scrollHeight = self.scrollObj.frame.size.height - 40
let scrollHeightString = String(describing: scrollHeight)
print(scrollHeightString)
var firstTextView = UIView() // this is temporary view
var columnIndex: CGFloat = 0
for _ in 0 ..< 5 {
let textViewSample = UITextView()
textViewSample.translatesAutoresizingMaskIntoConstraints = false
//textViewSample.attributedText = self.htmlString.utf8Data?.attributedString
textViewSample.isScrollEnabled = false
textViewSample.tag = Int(columnIndex)
textViewSample.backgroundColor = UIColor.green
self.scrollObj.addSubview(textViewSample)
if columnIndex == 0{
//here i am setting first view to left margin.
self.scrollObj.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[textViewSample]", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["textViewSample":textViewSample]))
//height to textview
self.scrollObj.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:[textViewSample(200)]", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["textViewSample":textViewSample]))
//width to textview
self.scrollObj.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:[textViewSample(200)]", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["textViewSample":textViewSample]))
}else{
//setting horizontal space to Temp view and current view
self.scrollObj.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-[firstTextView]-(10)-[textViewSample]", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["textViewSample":textViewSample,"firstTextView":firstTextView]))
//setting equal width and equal height to second textview based on first
self.scrollObj.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:[firstTextView][textViewSample(==firstTextView)]", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["textViewSample":textViewSample,"firstTextView":firstTextView]))
}
//y position to textview
self.scrollObj.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-(20)-[textViewSample]", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["textViewSample":textViewSample]))
firstTextView = textViewSample//assigning current view to temp view.
// Increase the current offset
columnIndex = columnIndex + 1
}
self.scrollObj.contentSize = CGSize(width: columnIndex*200, height: columnIndex*200)
self.scrollObj .setNeedsLayout()
self.scrollObj.layoutIfNeeded()
}
function(){
设scrollHeight=self.scrollObj.frame.size.height-40
让scrollHeightString=String(描述:scrollHeight)
打印(滚动高度字符串)
var firstTextView=UIView()//这是临时视图
变量列索引:CGFloat=0
对于0..<5中的uu{
让textViewSample=UITextView()
textViewSample.TranslatesAutoResizezingMaskintoConstraints=false
//textViewSample.attributedText=self.htmlString.utf8Data?.attributedString
textViewSample.IsScrolEnabled=false
textViewSample.tag=Int(columnIndex)
textViewSample.backgroundColor=UIColor.green
self.scrollObj.addSubview(textViewSample)
如果columnIndex==0{
//在这里,我将第一个视图设置为左边距。
self.scrollObj.addConstraints(NSLayoutConstraint.constraints(带可视格式:“H:|[textViewSample]”),选项:NSLayoutFormatOptions(rawValue:0),度量:nil,视图:[“textViewSample”:textViewSample]))
//文本视图的高度
self.scrollObj.addConstraints(NSLayoutConstraint.constraints(带可视格式:“V:[textViewSample(200)]”,选项:NSLayoutFormatOptions(rawValue:0),度量:nil,视图:[“textViewSample”:textViewSample]))
//文本视图的宽度
self.scrollObj.addConstraints(NSLayoutConstraint.constraints(带可视格式:“H:[textViewSample(200)]”,选项:NSLayoutFormatOptions(rawValue:0),度量:nil,视图:[“textViewSample”:textViewSample]))
}否则{
//将水平空间设置为临时视图和当前视图
self.scrollObj.addConstraints(NSLayoutConstraint.constraints(使用VisualFormat:|-[firstTextView]-(10)-[textViewSample]”,选项:NSLayoutFormatOptions(rawValue:0),度量:nil,视图:[“textViewSample”:textViewSample,“firstTextView”:firstTextView]))
//基于第一个文本视图设置第二个文本视图的等宽等高
self.scrollObj.addConstraints(NSLayoutConstraint.constraints(具有可视化格式:“H:[firstTextView][textViewSample(=firstTextView)]”),选项:NSLayoutFormatOptions(rawValue:0),度量:nil,视图:[“textViewSample”:textViewSample,“firstTextView”:firstTextView]))
}
//文本视图的y位置
self.scrollObj.addConstraints(NSLayoutConstraint.constraints(带可视格式:“V:|-(20)-[textViewSample]”),选项:NSLayoutFormatOptions(rawValue:0),度量:nil,视图:[“textViewSample”:textViewSample]))
firstTextView=textViewSample//将当前视图分配给临时视图。
//增加当前偏移量
columnIndex=columnIndex+1
}
self.scrollObj.contentSize=CGSize(宽度:columnIndex*200,高度:columnIndex*200)
self.scrollObj.setNeedsLayout()
self.scrollObj.layoutifneed()文件
}
这就是我的设计:-
如果要使用约束,可以执行以下操作:
var previousAnchor = scrollView.leadingAnchor
for _ in 0 ..< 5 {
let textView = UITextView()
textView.translatesAutoresizingMaskIntoConstraints = false
textView.backgroundColor = .green
textView.isScrollEnabled = false
scrollView.addSubview(textView)
NSLayoutConstraint.activate([
textView.leadingAnchor.constraint(equalTo: previousAnchor, constant: 10),
textView.heightAnchor.constraint(equalToConstant: 200),
textView.widthAnchor.constraint(equalToConstant: 200),
textView.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 10),
textView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: -10)
])
previousAnchor = textView.trailingAnchor
}
previousAnchor.constraint(equalTo: scrollView.trailingAnchor, constant: -10).isActive = true
同样,您说过希望滚动视图的高度小于10(大概在两侧)。因此,您可以执行类似操作,再次将200pt固定高度约束替换为:
textView.heightAnchor.constraint(equalTo: scrollViewContainer.heightAnchor, constant: -20)
现在,由于您无法引用scrollview的边界
,我所做的是将scroll视图放在容器视图中(scrollViewContainer
),因此此父视图的边界与scroll视图的边界相同。现在,约束可以引用此父视图,您将相对于滚动视图的边界而不是滚动视图的contentSize
设置这些子视图
但当您这样做时,您会看到滚动视图中的前三个视图(我可以向右滚动查看其余视图):
在我的演示中,我已经做到了这一点 在
ViewDidLoad
// add scrollView
let scrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height))
self.view.addSubview(scrollView)
// scrollview contraints
scrollView.translatesAutoresizingMaskIntoConstraints = false
scrollView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 0).isActive = true
scrollView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 0).isActive = true
scrollView.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 0).isActive = true
scrollView.rightAnchor.constraint(equalTo: self.view.rightAnchor, constant: 0).isActive = true
// add viewContainer
let viewContainer = UIView(frame: CGRect(x: 0, y: 0, width: scrollView.frame.size.width, height: scrollView.frame.size.height)) // View just after the SV
viewContainer.backgroundColor = UIColor.lightGray
scrollView.addSubview(viewContainer)
// viewcontainer contraints
//viewContainer.translatesAutoresizingMaskIntoConstraints = false
viewContainer.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 0).isActive = true
viewContainer.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 0).isActive = true
viewContainer.leftAnchor.constraint(equalTo: scrollView.leftAnchor, constant: 0).isActive = true
viewContainer.rightAnchor.constraint(equalTo: scrollView.rightAnchor, constant: 0).isActive = true
// add different subview in scrollview
var originY:Int = 0
for i in 0 ..< 5 {
let myInnerView = UIView(frame: CGRect(x: 0, y: originY , width: Int(scrollView.frame.size.width), height: 100))
myInnerView.translatesAutoresizingMaskIntoConstraints = false
viewContainer.addSubview(myInnerView)
// for different UI different color
switch i {
case 0:
myInnerView.backgroundColor = UIColor.green
break
case 1:
myInnerView.backgroundColor = UIColor.purple
break
case 2:
myInnerView.backgroundColor = UIColor.yellow
break
case 3:
myInnerView.backgroundColor = UIColor.orange
break
case 4:
myInnerView.backgroundColor = UIColor.blue
break
default: break
}
originY = originY+100+20
}
输出:
如果您需要放置动态视图,请使用UIStackView,我在堆栈视图中没有经验,这正是我所希望的。非常感谢@the_dahiya。。这非常有用,上面的答案对我很有帮助。您能检查一下这种非常有效的方法吗。。非常感谢先生!!当旋转到横向时,它不会被调整,我不想高度滚动,只想水平滚动。。。我正在设置textview高度,如下所示。。override func DIDROATE(来自fromInterfaceOrientation:UIInterfaceOrientation){scrollHeight=Int(self.scrollObj.bounds.size.height-20)scrollWidth=Int(self.scrollObj.bounds.size.width/3-10)self.view.LayoutFneed()self.scrollObj.LayoutFneed()}200x200如果“检查视图”显示在“否”,我希望我的文本视图大小为从10像素开始的顶部,从10像素开始的底部,文本视图宽度基于滚动视图宽度/3我希望宽度大小基于三列滚动视图宽度挑战在于,在约束条件下,滚动视图及其子视图之间的约束中的引用指向滚动视图的
contentSize
,而不是滚动视图的帧
/边界
。因此,您必须参考滚动视图的父视图。但一旦你这样做了,你可以有高度-20和宽度/3-10(或其排列),当设备旋转时自动调整。见上面修改的答案。
// add scrollView
let scrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height))
self.view.addSubview(scrollView)
// scrollview contraints
scrollView.translatesAutoresizingMaskIntoConstraints = false
scrollView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 0).isActive = true
scrollView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 0).isActive = true
scrollView.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 0).isActive = true
scrollView.rightAnchor.constraint(equalTo: self.view.rightAnchor, constant: 0).isActive = true
// add viewContainer
let viewContainer = UIView(frame: CGRect(x: 0, y: 0, width: scrollView.frame.size.width, height: scrollView.frame.size.height)) // View just after the SV
viewContainer.backgroundColor = UIColor.lightGray
scrollView.addSubview(viewContainer)
// viewcontainer contraints
//viewContainer.translatesAutoresizingMaskIntoConstraints = false
viewContainer.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 0).isActive = true
viewContainer.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 0).isActive = true
viewContainer.leftAnchor.constraint(equalTo: scrollView.leftAnchor, constant: 0).isActive = true
viewContainer.rightAnchor.constraint(equalTo: scrollView.rightAnchor, constant: 0).isActive = true
// add different subview in scrollview
var originY:Int = 0
for i in 0 ..< 5 {
let myInnerView = UIView(frame: CGRect(x: 0, y: originY , width: Int(scrollView.frame.size.width), height: 100))
myInnerView.translatesAutoresizingMaskIntoConstraints = false
viewContainer.addSubview(myInnerView)
// for different UI different color
switch i {
case 0:
myInnerView.backgroundColor = UIColor.green
break
case 1:
myInnerView.backgroundColor = UIColor.purple
break
case 2:
myInnerView.backgroundColor = UIColor.yellow
break
case 3:
myInnerView.backgroundColor = UIColor.orange
break
case 4:
myInnerView.backgroundColor = UIColor.blue
break
default: break
}
originY = originY+100+20
}
override func didRotate(from fromInterfaceOrientation: UIInterfaceOrientation) {
self.view.layoutIfNeeded()
}