在 xcode 8 的界面生成器中使用乘数自动布局为不同的屏幕尺寸创建可自动调整大小的视图
creating auto resizeable views for different screen size in interface builder of xcode 8 using auto layout using multipliers
我已经尝试在 IB
中使用 Autoresizing
实现此目的,使用 constraints
例如
- 固定,
- 宽高比,
- 垂直间距,
- horizontal/vertical间距,
- leading/trailing space;
但 none 似乎对所有屏幕尺寸都适用。
例如
iphone 7
中的 4 个图像视图是它们所需的输出位置,但是一旦我在 iphone 7 plus
屏幕尺寸或 iphone SE
屏幕尺寸中检查它,这些图像视图就会改变位置。
下面是 iphone 7.
的预期输出
iphone7 图片
下面是 预期的 输出,因为 4 个图像视图的位置在 iphone 7 plus 上发生了变化。
iphone7plus
我想再分享一张 iPhone SE 的图片,其中所有 4 张图片视图的位置变化更大,但无法分享,因为声誉低于 10
我会解释,例如,从第一个图像,即iphone 7,这4个小图像视图可以与白色背景的图像视图一起作为预期位置,但在其他两个屏幕中sizes(iphone7 plus and iphoneSE) 所有views(4 small image view and the view with white background) should have positioned and 与第一个外观相比相应地缩放。
更新:添加了代码
我刚刚对 @diana_prodan 在 post 中得到的答案之一进行了一些更改,以获得预期的输出。
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var imgOne: UIImageView!
@IBOutlet weak var imgTwo: UIImageView!
@IBOutlet weak var imgThree: UIImageView!
@IBOutlet weak var imgFour: UIImageView!
let icon_small : Float = 45.0
let icon_medium : Float = 50.0
override func viewDidLoad() {
super.viewDidLoad()
let viewSize = UIScreen.main.bounds.size
print(viewSize)
//image positioned
//for 4' screen
if (viewSize.height == 568.0){
addImageAtPosition(imgOne, icon_small,41, 106 )
addImageAtPosition(imgTwo, icon_small,105,91 )
addImageAtPosition(imgThree, icon_small,105, 147)
addImageAtPosition(imgFour, icon_small,139, 197 )
//for 4.7' screen
}else if(viewSize.height == 667.0){
addImageAtPosition(imgOne, icon_medium,52, 135 )
addImageAtPosition(imgTwo, icon_medium,127,106 )
addImageAtPosition(imgThree, icon_medium,127, 172 )
addImageAtPosition(imgFour, icon_medium,167, 230 )
//for 5.5' screen
}else if(viewSize.height == 736.0){
//add code woth cordinates for 5.5 screen size iPhone
}
}
//method to positon image views
func addImageAtPosition(_ img:UIImageView, _ size: Float, _ y: Float, _ x: Float) {
let imageView = img
imageView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(imageView)
let imageSize: CGFloat = CGFloat(size)
let topConstraint = NSLayoutConstraint(item: imageView, attribute: .top, relatedBy: .equal, toItem: self.topLayoutGuide, attribute: .bottom, multiplier: 1, constant: CGFloat(y))
let leftContraint = NSLayoutConstraint(item: imageView, attribute: .left, relatedBy: .equal, toItem: self.view, attribute: .left, multiplier: 1, constant: CGFloat(x))
let widthConstraint = NSLayoutConstraint(item: imageView, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: imageSize)
let heightConstraint = NSLayoutConstraint(item: imageView, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: imageSize)
view.addConstraints([topConstraint, leftContraint, widthConstraint, heightConstraint])
}
}
此代码的问题是我必须获取所有图像视图在不同屏幕尺寸上的坐标并对其进行硬编码,我认为这不是一个好的做法
采用主视图高度的一半高度约束的视图 A。之后给所有图像相同的高度和宽度约束。给一个图像的 x,y 约束视图 A 的中心。并且 link 所有图像都设置了默认约束。
您必须为 ImageView 的顶部和左侧约束设置随机值。
func addImageAtRadomPosition() {
let imageView = UIImageView()
imageView.backgroundColor = UIColor.red
imageView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(imageView)
let imageSize: CGFloat = 50.0
let screenHeight = UIScreen.main.bounds.size.height
let screenWidth = UIScreen.main.bounds.size.width
// Get random values which will be used for top and left constraints
let randomYPosition = Int(arc4random_uniform(UInt32(screenHeight - imageSize)))
let randomXPosition = Int(arc4random_uniform(UInt32(screenWidth - imageSize)))
let topConstraint = NSLayoutConstraint(item: imageView, attribute: .top, relatedBy: .equal, toItem: self.topLayoutGuide, attribute: .bottom, multiplier: 1, constant: CGFloat(randomYPosition))
let leftContraint = NSLayoutConstraint(item: imageView, attribute: .left, relatedBy: .equal, toItem: self.view, attribute: .left, multiplier: 1, constant: CGFloat(randomXPosition))
let widthConstraint = NSLayoutConstraint(item: imageView, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: imageSize)
let heightConstraint = NSLayoutConstraint(item: imageView, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: imageSize)
view.addConstraints([topConstraint, leftContraint, widthConstraint, heightConstraint])
}
调用此方法的次数与您的 ImageView 数一样多
for _ in 0...5 {
addImageAtRadomPosition()
}
如果这是您的预期输出,请通知我,以便我可以描述如何实现这一点,如果不是,请告诉我您还期待什么。
在下方评论。
edit
当我 运行 在 iPhone 6+
中使用相同的 VC 时,我得到了以下输出。所以考虑这个输出。
为了达到预期的输出,我参考了这个参考 [reference]: https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/AnatomyofaConstraint.html ,所以我所要做的就是
- select其中一个视图按住ctrl+拖动到外部视图
- 然后 按住 shift 和 select 等宽 & 等高, 居中
在容器中水平放置 & 在容器中垂直居中。
- 然后 select每个约束线(黄色)或从视图控制器场景列修改乘数直到黄色线变成蓝色即直到
它满足我最初在视图控制器布局中放置图像视图的位置。
here is the screen shot link it shows where to select constraints one by one(on left) and modify multiplier(on right).
我已经尝试在 IB
中使用 Autoresizing
实现此目的,使用 constraints
例如
- 固定,
- 宽高比,
- 垂直间距,
- horizontal/vertical间距,
- leading/trailing space;
但 none 似乎对所有屏幕尺寸都适用。
例如
iphone 7
中的 4 个图像视图是它们所需的输出位置,但是一旦我在 iphone 7 plus
屏幕尺寸或 iphone SE
屏幕尺寸中检查它,这些图像视图就会改变位置。
下面是 iphone 7.
的预期输出iphone7 图片
下面是 预期的 输出,因为 4 个图像视图的位置在 iphone 7 plus 上发生了变化。 iphone7plus
我想再分享一张 iPhone SE 的图片,其中所有 4 张图片视图的位置变化更大,但无法分享,因为声誉低于 10
我会解释,例如,从第一个图像,即iphone 7,这4个小图像视图可以与白色背景的图像视图一起作为预期位置,但在其他两个屏幕中sizes(iphone7 plus and iphoneSE) 所有views(4 small image view and the view with white background) should have positioned and 与第一个外观相比相应地缩放。
更新:添加了代码 我刚刚对 @diana_prodan 在 post 中得到的答案之一进行了一些更改,以获得预期的输出。
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var imgOne: UIImageView!
@IBOutlet weak var imgTwo: UIImageView!
@IBOutlet weak var imgThree: UIImageView!
@IBOutlet weak var imgFour: UIImageView!
let icon_small : Float = 45.0
let icon_medium : Float = 50.0
override func viewDidLoad() {
super.viewDidLoad()
let viewSize = UIScreen.main.bounds.size
print(viewSize)
//image positioned
//for 4' screen
if (viewSize.height == 568.0){
addImageAtPosition(imgOne, icon_small,41, 106 )
addImageAtPosition(imgTwo, icon_small,105,91 )
addImageAtPosition(imgThree, icon_small,105, 147)
addImageAtPosition(imgFour, icon_small,139, 197 )
//for 4.7' screen
}else if(viewSize.height == 667.0){
addImageAtPosition(imgOne, icon_medium,52, 135 )
addImageAtPosition(imgTwo, icon_medium,127,106 )
addImageAtPosition(imgThree, icon_medium,127, 172 )
addImageAtPosition(imgFour, icon_medium,167, 230 )
//for 5.5' screen
}else if(viewSize.height == 736.0){
//add code woth cordinates for 5.5 screen size iPhone
}
}
//method to positon image views
func addImageAtPosition(_ img:UIImageView, _ size: Float, _ y: Float, _ x: Float) {
let imageView = img
imageView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(imageView)
let imageSize: CGFloat = CGFloat(size)
let topConstraint = NSLayoutConstraint(item: imageView, attribute: .top, relatedBy: .equal, toItem: self.topLayoutGuide, attribute: .bottom, multiplier: 1, constant: CGFloat(y))
let leftContraint = NSLayoutConstraint(item: imageView, attribute: .left, relatedBy: .equal, toItem: self.view, attribute: .left, multiplier: 1, constant: CGFloat(x))
let widthConstraint = NSLayoutConstraint(item: imageView, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: imageSize)
let heightConstraint = NSLayoutConstraint(item: imageView, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: imageSize)
view.addConstraints([topConstraint, leftContraint, widthConstraint, heightConstraint])
}
}
此代码的问题是我必须获取所有图像视图在不同屏幕尺寸上的坐标并对其进行硬编码,我认为这不是一个好的做法
采用主视图高度的一半高度约束的视图 A。之后给所有图像相同的高度和宽度约束。给一个图像的 x,y 约束视图 A 的中心。并且 link 所有图像都设置了默认约束。
您必须为 ImageView 的顶部和左侧约束设置随机值。
func addImageAtRadomPosition() {
let imageView = UIImageView()
imageView.backgroundColor = UIColor.red
imageView.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(imageView)
let imageSize: CGFloat = 50.0
let screenHeight = UIScreen.main.bounds.size.height
let screenWidth = UIScreen.main.bounds.size.width
// Get random values which will be used for top and left constraints
let randomYPosition = Int(arc4random_uniform(UInt32(screenHeight - imageSize)))
let randomXPosition = Int(arc4random_uniform(UInt32(screenWidth - imageSize)))
let topConstraint = NSLayoutConstraint(item: imageView, attribute: .top, relatedBy: .equal, toItem: self.topLayoutGuide, attribute: .bottom, multiplier: 1, constant: CGFloat(randomYPosition))
let leftContraint = NSLayoutConstraint(item: imageView, attribute: .left, relatedBy: .equal, toItem: self.view, attribute: .left, multiplier: 1, constant: CGFloat(randomXPosition))
let widthConstraint = NSLayoutConstraint(item: imageView, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: imageSize)
let heightConstraint = NSLayoutConstraint(item: imageView, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: imageSize)
view.addConstraints([topConstraint, leftContraint, widthConstraint, heightConstraint])
}
调用此方法的次数与您的 ImageView 数一样多
for _ in 0...5 {
addImageAtRadomPosition()
}
如果这是您的预期输出,请通知我,以便我可以描述如何实现这一点,如果不是,请告诉我您还期待什么。
在下方评论。
edit
当我 运行 在 iPhone 6+
中使用相同的 VC 时,我得到了以下输出。所以考虑这个输出。
为了达到预期的输出,我参考了这个参考 [reference]: https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/AnatomyofaConstraint.html ,所以我所要做的就是
- select其中一个视图按住ctrl+拖动到外部视图
- 然后 按住 shift 和 select 等宽 & 等高, 居中 在容器中水平放置 & 在容器中垂直居中。
- 然后 select每个约束线(黄色)或从视图控制器场景列修改乘数直到黄色线变成蓝色即直到 它满足我最初在视图控制器布局中放置图像视图的位置。
here is the screen shot link it shows where to select constraints one by one(on left) and modify multiplier(on right).