在 UIButton 中放置一个 UIActivityIndicator
Posted
技术标签:
【中文标题】在 UIButton 中放置一个 UIActivityIndicator【英文标题】:Place a UIActivityIndicator inside a UIButton 【发布时间】:2013-03-07 10:54:06 【问题描述】:我知道我错过了一些愚蠢的东西,但无论如何,这是我的代码:
UIActivityIndicatorView indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
indicator.hidesWhenStopped = YES;
indicator.frame = btnLogin.frame;
indicator.center = btnLogin.center;
[self.view addSubview:indicator];
[indicator bringSubviewToFront:indicator];
这是最终结果:
http://img542.imageshack.us/img542/8172/uiactivity.png
提前谢谢你!
【问题讨论】:
【参考方案1】:我认为您缺少的概念是视图的框架(及其中心)都与其父视图相关。根据您的屏幕截图,我猜您的文本字段和按钮都在充当容器的视图中。因此,您的按钮的框架和中心与该容器视图相关,而不是与视图控制器的整体视图相关。您将相同的框架和中心分配给活动指示器,但随后将指示器添加为主视图的子视图,而不是容器视图。因此,您现在有两个视图(按钮和指示器)具有相同的框架,但该框架与两个不同的超级视图相关。
最简单的更改就是将您的指标添加到您正在使用的容器视图中。但我建议将指示器添加为按钮的子视图,然后只需进行一些数学运算即可调整其位置。
UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
CGFloat halfButtonHeight = btnLogin.bounds.size.height / 2;
CGFloat buttonWidth = btnLogin.bounds.size.width;
indicator.center = CGPointMake(buttonWidth - halfButtonHeight , halfButtonHeight);
[btnLogin addSubview:indicator];
[indicator startAnimating];
附带说明:您在视图框架之后设置视图中心是多余的。此外,作为子视图添加的最后一个视图会自动成为前子视图。
【讨论】:
【参考方案2】:根据@Musa almatri 的回答,我创建了扩展:
extension UIButton
func loadingIndicator(show show: Bool)
let tag = 9876
if show
let indicator = UIActivityIndicatorView()
let buttonHeight = self.bounds.size.height
let buttonWidth = self.bounds.size.width
indicator.center = CGPointMake(buttonWidth/2, buttonHeight/2)
indicator.tag = tag
self.addSubview(indicator)
indicator.startAnimating()
else
if let indicator = self.viewWithTag(tag) as? UIActivityIndicatorView
indicator.stopAnimating()
indicator.removeFromSuperview()
那么你可以这样使用它:
yourButton.loadingIndicator(show: true) //hide -> show: false
【讨论】:
请注意,这会将指示器置于按钮的中心。CGPointMake(buttonWidth - halfButtonHeight , halfButtonHeight)
接受的答案放在右侧(以简单、聪明的方式,IMO)。
show
函数参数标签是多余的,因为它与参数名称相同。你可以写:func loadingIndicator(show: Bool)
.【参考方案3】:
这是一个 Swift 3 版本,没有使用标签。
import UIKit
extension UIButton
func loadingIndicator(show: Bool)
if show
let indicator = UIActivityIndicatorView()
let buttonHeight = self.bounds.size.height
let buttonWidth = self.bounds.size.width
indicator.center = CGPoint(x: buttonWidth/2, y: buttonHeight/2)
self.addSubview(indicator)
indicator.startAnimating()
else
for view in self.subviews
if let indicator = view as? UIActivityIndicatorView
indicator.stopAnimating()
indicator.removeFromSuperview()
【讨论】:
为什么这比带标签的更好?能详细点吗? 使用标签会增加额外的复杂性并可能导致错误,但我并不是说标签不好。此解决方案更简单,并查找 UIActivityIndicatorView 本身。 感谢您的解释。:) 为什么不indicator.center = self.center
?【参考方案4】:
小升级:(在superview上添加按钮)
extension UIButton
func loadingIndicator(_ show: Bool)
let indicatorTag = 808404
if show
isEnabled = false
alpha = 0
let indicator = UIActivityIndicatorView(activityIndicatorStyle: .gray)
indicator.center = center
indicator.tag = indicatorTag
superview?.addSubview(indicator)
indicator.startAnimating()
else
isEnabled = true
alpha = 1.0
if let indicator = superview?.viewWithTag(indicatorTag) as? UIActivityIndicatorView
indicator.stopAnimating()
indicator.removeFromSuperview()
【讨论】:
【参考方案5】:Swift 解决方案:
var indicator = UIActivityIndicatorView()
var halfButtonHeight = SOME_BUTTON.bounds.size.height / 2;
var buttonWidth = SOME_BUTTON.bounds.size.width;
indicator.center = CGPointMake(buttonWidth - halfButtonHeight , halfButtonHeight);
SOME_BUTTON.addSubview(indicator)
indicator.startAnimating()
并使其位于按钮的中心
indicator.center = CGPointMake(buttonWidth/2, halfButtonHeight);
或者使用优秀的库
https://github.com/souzainf3/RNLoadingButton-Swift
【讨论】:
buttonWidth - halfButtonHeight
:从宽度中减去高度,似乎是错误的。然后,第一个 indicator.center
分配是无用的,因为还有第二个。最后,x
是什么?【参考方案6】:
我正在使用约束来使 UIButton 内的指示器居中。 改编@DanielQ 的扩展,就变成了:
extension UIButton
func loadingIndicator(show: Bool)
let tag = 9876
if show
let indicator = UIActivityIndicatorView()
indicator.tag = tag
self.addSubview(indicator)
indicator.translatesAutoresizingMaskIntoConstraints = false
let horizontalConstraint = NSLayoutConstraint(item: indicator, attribute: NSLayoutAttribute.centerX, relatedBy: NSLayoutRelation.equal, toItem: self, attribute: NSLayoutAttribute.centerX, multiplier: 1, constant: 0)
let verticalConstraint = NSLayoutConstraint(item: indicator, attribute: NSLayoutAttribute.centerY, relatedBy: NSLayoutRelation.equal, toItem: self, attribute: NSLayoutAttribute.centerY, multiplier: 1, constant: 0)
self.addConstraints([horizontalConstraint, verticalConstraint])
indicator.startAnimating()
else
if let indicator = self.viewWithTag(tag) as? UIActivityIndicatorView
indicator.stopAnimating()
indicator.removeFromSuperview()
【讨论】:
【参考方案7】:我从按钮中删除了标题,然后在动画完成后将其添加回来,而不是覆盖标题的指示器:
extension UIButton
func loadingIndicator(show: Bool)
let tag = 9876
var color: UIColor?
if show
color = titleColor(for: .normal)
let indicator = UIActivityIndicatorView()
let buttonHeight = self.bounds.size.height
let buttonWidth = self.bounds.size.width
indicator.center = CGPoint(x: buttonWidth/2, y: buttonHeight/2)
indicator.tag = tag
indicator.color = UIColor.white
setTitleColor(.clear, for: .normal)
self.addSubview(indicator)
indicator.startAnimating()
else
if let indicator = self.viewWithTag(tag) as? UIActivityIndicatorView
indicator.stopAnimating()
indicator.removeFromSuperview()
setTitleColor(color, for: .normal)
【讨论】:
以上是关于在 UIButton 中放置一个 UIActivityIndicator的主要内容,如果未能解决你的问题,请参考以下文章
UISegmentedView 中的 UIButton 没有被按下
UIButton UIPopUpController 以编程方式
避免 UIPickerView ios 上的 UIButton 覆盖