我如何知道我是否使 auto-layout 足够好以适合所有设备?
How do I know if I made auto-layout good enough to fit every device?
就我而言:
当我在 Ipod touch 7th gen 上将设备设置为 Iphone SE 和 运行 模拟器时,一切正常,每个元素都在应有的位置。
但是,如果我在同一个模拟器(第 7 代 IPod touch)上将设备更改为 iPhone 11 和 运行,几乎所有东西都搞砸了。我应该始终将设备设置为与模拟器设备相同还是无关紧要?
.
这个问题的标题也是我的问题:Does Xcode storyboard device and simulator needs to be same ?
编辑:
上层堆栈视图(用户名;密码)导致了我的问题,这就是我是如何做到的。
首先,我添加了堆栈视图,然后在里面放了两个文本字段。
堆栈视图组件:
轴:垂直
对齐方式:填充
分配:平均填充
间距:30
堆栈视图约束:
将 X 中心对齐到:安全区域
顶部 Space 至:图像(堆栈视图上方的图像)
等于:17.6
纵横比:Superview
Instrinct Size(默认)以及其他所有内容都是默认的
用户名标签只有一个约束,其宽高比= 6:1
按钮自定义造成了问题,这是我使用的:
class customElements{
static func styleTextField(_ textfield:UITextField) {
// Create the bottom line
let bottomLine = CALayer()
bottomLine.frame = CGRect(x: 0, y: textfield.frame.height - 2, width: textfield.frame.width, height: 2)
bottomLine.backgroundColor = UIColor.init(red: 48/255, green: 173/255, blue: 99/255, alpha: 1).cgColor
// Remove border on text field
textfield.borderStyle = .none
// Add the line to the text field
textfield.layer.addSublayer(bottomLine)
}
好的 - 所以问题不在于 auto-layout...
问题是您的代码 错误地设置了“bottomLine”层的框架。
您很可能在 viewDidLoad()
中调用 styleTextField()
函数。但是,UIKit 尚未设置视图/UI 元素的框架。
您需要等到帧设置完毕 - 例如 viewDidLayoutSubviews()
。但是会出现一个新问题,因为它可以(并且通常)被多次调用,并且您的代码将创建和添加多个“bottomLine”层。
更好的选择是子class UITextField
并在layoutSubviews()
.
中处理图层框架
这是一个快速示例:
@IBDesignable
class StyleTextField: UITextField {
@IBInspectable
var lineColor: UIColor = UIColor.init(red: 48/255, green: 173/255, blue: 99/255, alpha: 1) {
didSet {
bottomLine.backgroundColor = lineColor.cgColor
}
}
private let bottomLine: CALayer = CALayer()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
// needs to be set here for Storyboard / IB
self.borderStyle = .none
}
private func commonInit() {
// remove border
self.borderStyle = .none
// bottom line color
bottomLine.backgroundColor = lineColor.cgColor
// add bottom line layer
layer.addSublayer(bottomLine)
}
override func layoutSubviews() {
super.layoutSubviews()
// update bottom line layer frame
bottomLine.frame = CGRect(x: 0, y: bounds.height - 2.0, width: bounds.width, height: 2)
}
}
现在,在 Storyboard / IB 中,当您将 StyleTextField
指定为 UITextField
的自定义 class 时,“bottomLine”将被自动添加和加框 - 无需调用任何其他函数。
并且,通过将其编码为 @IBDesignable
,我们可以看到它在 Storyboard 中的样子:
此外,我添加了 lineColor
作为 @IBInspectable
属性,作为您可以在 Storyboard 中更改的示例:
就我而言:
当我在 Ipod touch 7th gen 上将设备设置为 Iphone SE 和 运行 模拟器时,一切正常,每个元素都在应有的位置。
但是,如果我在同一个模拟器(第 7 代 IPod touch)上将设备更改为 iPhone 11 和 运行,几乎所有东西都搞砸了。我应该始终将设备设置为与模拟器设备相同还是无关紧要?
这个问题的标题也是我的问题:Does Xcode storyboard device and simulator needs to be same ?
编辑:
上层堆栈视图(用户名;密码)导致了我的问题,这就是我是如何做到的。 首先,我添加了堆栈视图,然后在里面放了两个文本字段。
堆栈视图组件: 轴:垂直 对齐方式:填充 分配:平均填充 间距:30
堆栈视图约束:
将 X 中心对齐到:安全区域
顶部 Space 至:图像(堆栈视图上方的图像) 等于:17.6
纵横比:Superview Instrinct Size(默认)以及其他所有内容都是默认的
用户名标签只有一个约束,其宽高比= 6:1
按钮自定义造成了问题,这是我使用的:
class customElements{
static func styleTextField(_ textfield:UITextField) {
// Create the bottom line
let bottomLine = CALayer()
bottomLine.frame = CGRect(x: 0, y: textfield.frame.height - 2, width: textfield.frame.width, height: 2)
bottomLine.backgroundColor = UIColor.init(red: 48/255, green: 173/255, blue: 99/255, alpha: 1).cgColor
// Remove border on text field
textfield.borderStyle = .none
// Add the line to the text field
textfield.layer.addSublayer(bottomLine)
}
好的 - 所以问题不在于 auto-layout...
问题是您的代码 错误地设置了“bottomLine”层的框架。
您很可能在 viewDidLoad()
中调用 styleTextField()
函数。但是,UIKit 尚未设置视图/UI 元素的框架。
您需要等到帧设置完毕 - 例如 viewDidLayoutSubviews()
。但是会出现一个新问题,因为它可以(并且通常)被多次调用,并且您的代码将创建和添加多个“bottomLine”层。
更好的选择是子class UITextField
并在layoutSubviews()
.
这是一个快速示例:
@IBDesignable
class StyleTextField: UITextField {
@IBInspectable
var lineColor: UIColor = UIColor.init(red: 48/255, green: 173/255, blue: 99/255, alpha: 1) {
didSet {
bottomLine.backgroundColor = lineColor.cgColor
}
}
private let bottomLine: CALayer = CALayer()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
// needs to be set here for Storyboard / IB
self.borderStyle = .none
}
private func commonInit() {
// remove border
self.borderStyle = .none
// bottom line color
bottomLine.backgroundColor = lineColor.cgColor
// add bottom line layer
layer.addSublayer(bottomLine)
}
override func layoutSubviews() {
super.layoutSubviews()
// update bottom line layer frame
bottomLine.frame = CGRect(x: 0, y: bounds.height - 2.0, width: bounds.width, height: 2)
}
}
现在,在 Storyboard / IB 中,当您将 StyleTextField
指定为 UITextField
的自定义 class 时,“bottomLine”将被自动添加和加框 - 无需调用任何其他函数。
并且,通过将其编码为 @IBDesignable
,我们可以看到它在 Storyboard 中的样子:
此外,我添加了 lineColor
作为 @IBInspectable
属性,作为您可以在 Storyboard 中更改的示例: