我想在视图中添加UILabel
,当发生错误时向下滑动以向用户发送错误消息,3秒后它将向上滑动消失。它的原型就像Facebook或Instagram显示的那样。我在许多errorLabel
中需要ViewController
,因此我尝试将UILabel
子类化。这是我的子类ErrorLabel
:
class ErrorLabel: UILabel {
var errorString: String?
func sendErrorMessage() {
self.text = errorString
showErrorLabel()
let timer = NSTimer.scheduledTimerWithTimeInterval(3, target: self, selector: "hideErrorLabel", userInfo: nil, repeats: false)
}
func animateFrameChange() {
UIView.animateWithDuration(1, animations: { self.layoutIfNeeded() }, completion: nil)
}
func showErrorLabel() {
let oldFrame = self.frame
let newFrame = CGRectMake(oldFrame.origin.x, oldFrame.origin.y, oldFrame.height + 30, oldFrame.width)
self.frame = newFrame
self.animateFrameChange()
}
func hideErrorLabel() {
let oldFrame = self.frame
let newFrame = CGRectMake(oldFrame.origin.x, oldFrame.origin.y, oldFrame.height - 30, oldFrame.width)
self.frame = newFrame
self.animateFrameChange()
}
}
然后,我尝试将errorLabel
添加到ViewController
之一,如下所示:
class ViewController: UIViewController {
var errorLabel = ErrorLabel()
override func viewDidLoad() {
super.viewDidLoad()
let errorLabelFrame = CGRectMake(0, 20, self.view.frame.width, 0)
self.errorLabel.frame = errorLabelFrame
self.errorLabel.backgroundColor = translucentTurquoise
self.errorLabel.font = UIFont.systemFontOfSize(18)
self.errorLabel.textColor = UIColor.whiteColor()
self.errorLabel.textAlignment = NSTextAlignment.Center
self.view.addSubview(errorLabel)
self.view.bringSubviewToFront(errorLabel)
}
func aFunc(errorString: String) {
self.errorLabel.errorString = errorString
self.errorLabel.sendErrorMessage()
}
}
当我在iOS模拟器中运行它时,它无法正常工作:
errorLabel
左侧水平显示,中间垂直显示,I...
只有Invalid parameters
。self.view.frame.width
。你能告诉我什么是错的以及如何解决错误吗?
答案 0 :(得分:0)
我可能会部分解决您的问题。希望它有所帮助。
I...
。为此,您需要增加UILabel
的大小。 UIView.animateWithDuration
的完成块中使用相同的代码。请参阅此link 我建议你考虑使用Extensions
来完成你想要做的事情。
答案 1 :(得分:0)
我不是子类化UILabel,而是继承UIViewController,也许你已经完成了吗?让我们调用子类--BaseViewController,让我们所有的UIViewControllers子类化这个类。
然后我将以编程方式创建一个UIView,其中包含此BaseViewController类中的垂直和水平居中的UILabel。这里重要的部分是为它创建NSLayoutConstraints。然后我会通过更改约束的值来隐藏和显示它。
我会使用名为pod的优秀Cartography来创建约束,这使得它非常简单和干净!
使用此解决方案,您应该能够在任何UIViewControllers中显示或隐藏错误消息
这是未经测试的代码,但希望非常接近您问题的解决方案。
import Cartography /* Requires that you have included Cartography in your Podfile */
class BaseViewController: UIViewController {
private var yPositionForErrorViewWhenVisible: Int { return 0 }
private var yPositionForErrorViewWhenInvisible: Int { return -50 }
private let hideDelay: NSTimeInterval = 3
private var timer: NSTimer!
var yConstraintForErrorView: NSLayoutConstraint!
var errorView: UIView!
var errorLabel: UILabel!
//MARK: - Initialization
required init(aDecoder: NSCoder) {
super.init(aDecoder)
setup()
}
//MARK: - Private Methods
private func setup() {
setupErrorView()
}
private func setupErrorView() {
errorView = UIView()
errorLabel = UILabel()
errorView.addSubview(errorLabel)
view.addSubview(errorView)
/* Set constraints between viewController and errorView and errorLabel */
layout(view, errorView, errorLabel) {
parent, errorView, errorLabel in
errorView.width == parent.width
errorView.centerX == parent.centerX
errorView.height == 50
/* Capture the y constraint, which defaults to be 50 points out of screen, so that it is not visible */
self.yConstraintForErrorView = (errorView.top == parent.top - self.yPositionForErrorViewWhenInvisible)
errorLabel.height = 30
errorLabel.width == errorView.width
errorLabel.centerX == errorView.centerX
errorLabel.centerY = errorView.centerY
}
}
private func hideOrShowErrorMessage(hide: Bool, animated: Bool) {
if hide {
yConstraintForErrorView.constant = yPositionForErrorViewWhenInvisible
} else {
yConstraintForErrorView.constant = yPositionForErrorViewWhenVisible
}
let automaticallyHideErrorViewClosure: () -> Void = {
/* Only scheduling hiding of error message, if we just showed it. */
if show {
automaticallyHideErrorMessage()
}
}
if animated {
view.animateConstraintChange(completion: {
(finished: Bool) -> Void in
automaticallyHideErrorViewClosure()
})
} else {
view.layoutIfNeeded()
automaticallyHideErrorViewClosure()
}
}
private func automaticallyHideErrorMessage() {
if timer != nil {
if timer.valid {
timer.invalidate()
}
timer = nil
}
timer = NSTimer.scheduledTimerWithTimeInterval(hideDelay, target: self, selector: "hideErrorMessage", userInfo: nil, repeats: false)
}
//MARK: - Internal Methods
func showErrorMessage(message: String, animated: Bool = true) {
errorLabel.text = message
hideOrShowErrorMessage(false, animated: animated)
}
//MARK: - Selector Methods
func hideErrorMessage(animated: Bool = true) {
hideOrShowErrorMessage(true, animated: animated)
}
}
extension UIView {
static var standardDuration: NSTimeInterval { return 0.3 }
func animateConstraintChange(duration: NSTimeInterval = standardDuration, completion: ((Bool) -> Void)? = nil) {
UIView.animate(durationUsed: duration, animations: {
() -> Void in
self.layoutIfNeeded()
}, completion: completion)
}
}