当 UIButton.Configuration.showsActivityIndicator 为 true 和 false 时,确保按钮高度一致

Ensure consistent button height when UIButton.Configuration.showsActivityIndicator is true and false

提问人:Jordan H 提问时间:11/14/2023 更新时间:11/15/2023 访问量:19

问:

使用以下代码时,按钮高度为 28.33,同时使用默认的大动态类型大小。当您点击按钮启用时,高度意外增加到 34.33。字体越小,用户的动态字体大小越大,按钮高度不一致越明显。showsActivityIndicator

let button = UIButton(configuration: {
    var config = UIButton.Configuration.filled()
    config.title = "Button"
    config.titleTextAttributesTransformer = UIConfigurationTextAttributesTransformer {
        var container = $0
        container.uiKit.font = .preferredFont(forTextStyle: .caption1)
        return container
    }
    return config
}())
button.addAction(UIAction() { _ in
    button.configuration?.showsActivityIndicator = true
}, for: .touchUpInside)

问题似乎在于按钮高度由内容插图确定,而这些插图是相对于按钮中的最大内容而言的。最初,按钮中的唯一内容是标题文本,因此它的高度较小,然后添加活动指示器,其高度大于标题文本,因此按钮高度增加,以确保内容插图相对于最高内容得到尊重。有没有办法解决这个问题,使按钮高度在其非加载和加载状态下保持不变(除了强制固定高度约束)?也许有一种方法可以将内容插图更改为始终相对于非加载状态下的活动指示器高度?

iOS UIKit的 UIBuint

评论


答:

0赞 DonMag 11/14/2023 #1

一种选择--可能对你有用......

来自 Apple 的文档:

showsActivityIndicator(显示活动指示器)

一个 Boolean 值,该值确定按钮是否显示活动指示器而不是图像。

“微调器”的默认大小是在@2x显示器上,在@3x显示器上。20.5 x 20.520.333... x 20.333...

因此,我们可以将清晰的图像设置为该大小,并调整标题,以便在活动指示器未显示时水平居中。.contentInsets

像这样的东西:

let v: CGFloat = 20.0 + 1.0 / UIScreen.main.scale
// create a clear image
let img = UIGraphicsImageRenderer(size: .init(width: v, height: v)).image { _ in }
let button = UIButton(configuration: {
    var config = UIButton.Configuration.filled()
    config.title = "Button"
    config.titleTextAttributesTransformer = UIConfigurationTextAttributesTransformer {
        var container = $0
        container.uiKit.font = .preferredFont(forTextStyle: .caption1)
        return container
    }
    config.image = img
    // default instets are 7, 12, 7, 12
    //  so we need to add the image width to the right
    config.contentInsets = .init(top: 7.0, leading: 12.0, bottom: 7.0, trailing: 12.0 + v)
    return config
}())

button.addAction(UIAction() { _ in
    button.configuration?.showsActivityIndicator.toggle()
}, for: .touchUpInside)

编辑

似乎没有任何属性可以设置可以为您提供所需的控制权......

您可以使用上面的代码(清晰图像)并在 Trait 更改时更新图像...

或者 -- 一种“蛮力”解决方法,同样可能对你有用:

创建一个按钮(具有匹配的属性),可以隐藏在视图之外,也可以位于视图之外,并设置其 ...,然后将可见按钮的高度限制不可见按钮的高度。config.showsActivityIndicator = true

评论

0赞 Jordan H 11/14/2023
活动指示器大小随动态类型而变化,因此仅当您使用较大的文本大小时,这才有效。
0赞 DonMag 11/15/2023
@JordanH - 好点子。请参阅编辑我的答案。
0赞 Jordan H 11/15/2023
这是一个有趣的想法,会奏效,非常恶心,但它会奏效哈