使用 Interface Builder 设置插图不起作用
Setting insets with Interface Builder doesn't work
我关注了 Hacking With Swift's Project 2,但我对 Interface Builder 有非常模糊的(即我不知道发生了什么)问题。
我已经按照教程中的描述构建了布局:
- 3 个按钮,彼此之间的间距限制为 30px
- 每个按钮都包含一个旗帜图像
- 每个按钮的大小为 200x100
当我 运行 解决 AutoLayout 问题时,所有按钮的大小都调整为 224x114 并获得无法使用 Interface Builder 删除的填充(所有插入设置为 0,按钮的内容模式设置为缩放以适合)。这只能通过代码应用填充来解决:
button1.configuration?.contentInsets = NSDirectionalEdgeInsets.zero
button2.configuration?.contentInsets = NSDirectionalEdgeInsets.zero
button3.configuration?.contentInsets = NSDirectionalEdgeInsets.zero
我已经将我的 Storyboard 与 HWS 存储库中的代码进行了比较,但没有发现任何不同。
完整代码如下:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var button1: UIButton!
@IBOutlet weak var button2: UIButton!
@IBOutlet weak var button3: UIButton!
var countries = [String]()
var correctAnswer = 0
var answeredQuestions = 0
var score = 0
override func viewDidLoad() {
super.viewDidLoad()
countries += [
"estonia", "france", "germany", "ireland",
"italy", "monaco", "nigeria", "poland",
"russia", "spain", "uk", "us"
]
button1.configuration?.contentInsets = NSDirectionalEdgeInsets.zero
button2.configuration?.contentInsets = NSDirectionalEdgeInsets.zero
button3.configuration?.contentInsets = NSDirectionalEdgeInsets.zero
button1.layer.borderWidth = 1
button2.layer.borderWidth = 1
button3.layer.borderWidth = 1
button1.layer.borderColor = UIColor.lightGray.cgColor
button2.layer.borderColor = UIColor.lightGray.cgColor
button3.layer.borderColor = UIColor.lightGray.cgColor
askQuestion()
}
func askQuestion(action: UIAlertAction! = nil) {
countries.shuffle()
correctAnswer = Int.random(in: 0...2)
let answer = countries[correctAnswer].uppercased()
title = "\(answer) – score: \(score)"
button1.setImage(UIImage(named: countries[0]), for: .normal)
button2.setImage(UIImage(named: countries[1]), for: .normal)
button3.setImage(UIImage(named: countries[2]), for: .normal)
}
@IBAction func buttonTapped(_ sender: UIButton) {
var title: String
var message: String
var buttonText: String
answeredQuestions += 1
if (sender.tag == correctAnswer) {
title = "Correct"
score += 1
} else {
let answer = countries[correctAnswer].uppercased()
title = "Wrong! That's the flag of \(answer)"
score -= 1
}
if (answeredQuestions >= 10) {
message = "Your final score is \(score)."
buttonText = "Restart"
answeredQuestions = 0
score = 0
} else {
message = "Your score is \(score)."
buttonText = "Continue"
}
let ac = UIAlertController(title: title, message: message, preferredStyle: .alert)
ac.addAction(UIAlertAction(title: buttonText, style: .default, handler: askQuestion))
present(ac, animated: true)
}
}
这就是我在 IB 中设置按钮的方式:
两件事....
第一条评论:这可能是由新的按钮样式引起的。如果将其从 Plain
更改为 Default
:
IB 应将尺寸保持在 200 x 100
。
第二条评论:更好的办法是 完全按照您的意愿分配约束 而不是依赖 IB 的“自动修复布局”。
在 iOS 15 中,添加了 UIButton.Configuration
API,这为 IB 添加了更多选项,并更改了按钮的外观。教程很可能是在这之前写的,并没有考虑到这一点。
目前,您在 IB 中添加的每个按钮都将默认使用 UIButton.Configuration
。这就是赋予它 insets 的原因,它是默认配置的一部分。除了在代码中设置,也可以在IB中的“后台配置”下设置:
如果您不想使用配置,而是想要 pre-iOS 15 行为,请将“样式”更改为“默认”:
我关注了 Hacking With Swift's Project 2,但我对 Interface Builder 有非常模糊的(即我不知道发生了什么)问题。
我已经按照教程中的描述构建了布局:
- 3 个按钮,彼此之间的间距限制为 30px
- 每个按钮都包含一个旗帜图像
- 每个按钮的大小为 200x100
当我 运行 解决 AutoLayout 问题时,所有按钮的大小都调整为 224x114 并获得无法使用 Interface Builder 删除的填充(所有插入设置为 0,按钮的内容模式设置为缩放以适合)。这只能通过代码应用填充来解决:
button1.configuration?.contentInsets = NSDirectionalEdgeInsets.zero
button2.configuration?.contentInsets = NSDirectionalEdgeInsets.zero
button3.configuration?.contentInsets = NSDirectionalEdgeInsets.zero
我已经将我的 Storyboard 与 HWS 存储库中的代码进行了比较,但没有发现任何不同。
完整代码如下:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var button1: UIButton!
@IBOutlet weak var button2: UIButton!
@IBOutlet weak var button3: UIButton!
var countries = [String]()
var correctAnswer = 0
var answeredQuestions = 0
var score = 0
override func viewDidLoad() {
super.viewDidLoad()
countries += [
"estonia", "france", "germany", "ireland",
"italy", "monaco", "nigeria", "poland",
"russia", "spain", "uk", "us"
]
button1.configuration?.contentInsets = NSDirectionalEdgeInsets.zero
button2.configuration?.contentInsets = NSDirectionalEdgeInsets.zero
button3.configuration?.contentInsets = NSDirectionalEdgeInsets.zero
button1.layer.borderWidth = 1
button2.layer.borderWidth = 1
button3.layer.borderWidth = 1
button1.layer.borderColor = UIColor.lightGray.cgColor
button2.layer.borderColor = UIColor.lightGray.cgColor
button3.layer.borderColor = UIColor.lightGray.cgColor
askQuestion()
}
func askQuestion(action: UIAlertAction! = nil) {
countries.shuffle()
correctAnswer = Int.random(in: 0...2)
let answer = countries[correctAnswer].uppercased()
title = "\(answer) – score: \(score)"
button1.setImage(UIImage(named: countries[0]), for: .normal)
button2.setImage(UIImage(named: countries[1]), for: .normal)
button3.setImage(UIImage(named: countries[2]), for: .normal)
}
@IBAction func buttonTapped(_ sender: UIButton) {
var title: String
var message: String
var buttonText: String
answeredQuestions += 1
if (sender.tag == correctAnswer) {
title = "Correct"
score += 1
} else {
let answer = countries[correctAnswer].uppercased()
title = "Wrong! That's the flag of \(answer)"
score -= 1
}
if (answeredQuestions >= 10) {
message = "Your final score is \(score)."
buttonText = "Restart"
answeredQuestions = 0
score = 0
} else {
message = "Your score is \(score)."
buttonText = "Continue"
}
let ac = UIAlertController(title: title, message: message, preferredStyle: .alert)
ac.addAction(UIAlertAction(title: buttonText, style: .default, handler: askQuestion))
present(ac, animated: true)
}
}
这就是我在 IB 中设置按钮的方式:
两件事....
第一条评论:这可能是由新的按钮样式引起的。如果将其从 Plain
更改为 Default
:
IB 应将尺寸保持在 200 x 100
。
第二条评论:更好的办法是 完全按照您的意愿分配约束 而不是依赖 IB 的“自动修复布局”。
在 iOS 15 中,添加了 UIButton.Configuration
API,这为 IB 添加了更多选项,并更改了按钮的外观。教程很可能是在这之前写的,并没有考虑到这一点。
目前,您在 IB 中添加的每个按钮都将默认使用 UIButton.Configuration
。这就是赋予它 insets 的原因,它是默认配置的一部分。除了在代码中设置,也可以在IB中的“后台配置”下设置:
如果您不想使用配置,而是想要 pre-iOS 15 行为,请将“样式”更改为“默认”: