使用 Interface Builder 设置插图不起作用

Setting insets with Interface Builder doesn't work

我关注了 Hacking With Swift's Project 2,但我对 Interface Builder 有非常模糊的(即我不知道发生了什么)问题。

我已经按照教程中的描述构建了布局:

当我 运行 解决 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 行为,请将“样式”更改为“默认”: