iOS - 如何在 Swift 中创建没有第三方框架的自定义动画横幅
iOS - How to create custom animated banner without third party framework in Swift
我需要创建一个自定义下拉横幅,它会从顶部掉落,然后在几秒钟内上升。
对于自定义横幅 UIView,我指的是这个问题,这是一个完美的例子,这就是我想要的,因为我的横幅也是动态的,这将根据文本调整高度。
但不确定如何制作此动画。我已经为动画编写了代码并且它工作得很好但不确定这个动画如何与我上面提到的自定义视图一起工作。
@IBAction func buttonClicked(_ sender: Any) {
bannerView()
}
func bannerView() {
let container = UIView()
container.backgroundColor = UIColor.black
container.frame = CGRect(x: 0, y: -200, width: self.view.frame.width, height: 200)
UIApplication.shared.windows[0].addSubview(container)
DispatchQueue.main.async {
UIView.animate(withDuration: 0.4, delay: 0.0, options: .curveLinear, animations: {
container.frame = CGRect(x:0, y: 0, width: self.view.frame.size.width, height: 200)
}) { (finished) in
UIView.animate(withDuration: 0.4,delay: 2.0, options: .curveLinear, animations: {
container.frame = CGRect(x:0, y: -200, width: self.view.frame.size.width, height: 200)
})
}
}
}
@IBAction func buttonClicked(_ sender: Any) {
var stringText = "Lorem ipsum dolor sit amet,"
bannerNotification(text: stringText)
}
func bannerNotification(text: String) {
let container = UIView()
let image = UIImageView()
let label = UILabel()
container.frame = CGRect(x: 0, y:-100, width: self.view.frame.size.width, height: 100)
container.backgroundColor = .blue
image.frame = CGRect(x: 15, y: 60, width: 30, height: 30)
image.image = UIImage(named: "passport")
label.frame = CGRect(x: image.bounds.maxX + 35, y: 40, width: container.frame.size.width - 100, height: 50)
label.numberOfLines = 0
label.font = UIFont(name:"Helvetica Neue", size: 15)
label.text = text
container.addSubview(image)
container.addSubview(label)
UIApplication.shared.windows[0].addSubview(container)
DispatchQueue.main.async {
UIView.animate(withDuration: 0.4, delay: 0.0, options: .curveLinear, animations: {
container.frame = CGRect(x:0, y: 0, width: self.view.frame.size.width, height: 100)
}) { (finished) in
UIView.animate(withDuration: 0.4,delay: 2.0, options: .curveLinear, animations: {
container.frame = CGRect(x:0, y: -100, width: self.view.frame.size.width, height: 100)
})
}
}
}
试试这个,希望对你有用。
我不喜欢将子视图添加到 windows 而不是添加到视图层次结构...但是,如果这确实是您想要做的,请尝试一下(查看代码中的注释).
@IBAction func buttonClicked(_ sender: Any) {
bannerNotification(text: "Banner Test with lots of text to wrap onto multiple lines. We're using explict frames and calculating the height of the (potentially multiline) label.")
}
func bannerNotification(text: String){
// create a "container" view
let container = UIView()
// create a label
let label = UILabel()
// add label to container
container.addSubview(label)
// color / font / text properties as desired
container.backgroundColor = UIColor(red: 0.0, green: 0.5, blue: 1.0, alpha: 1.0)
label.backgroundColor = .yellow
label.numberOfLines = 0
label.font = UIFont(name:"Helvetica Neue", size: 16.0)
label.text = text
// padding on left/right of label
let hPadding: CGFloat = 16.0
// padding on top of label - account for status bar?
let vTopPadding: CGFloat = 32.0
// padding on bottom of label
let vBotPadding: CGFloat = 16.0
let width = UIScreen.main.bounds.width
// get reference to window 0
let w = UIApplication.shared.windows[0]
// add container to window
w.addSubview(container)
// calculate label height
let labelSize = label.systemLayoutSizeFitting(CGSize(width: width - (hPadding * 2.0),
height: UIView.layoutFittingCompressedSize.height))
// rect for container view - start with .zero
var containerRect = CGRect.zero
// set its size to screen width x calculated label height + top/bottom padding
containerRect.size = CGSize(width: width, height: labelSize.height + vTopPadding + vBotPadding)
// set container view's frame
container.frame = containerRect
// rect for label - container rect inset by padding values
let labelRect = containerRect.inset(by: UIEdgeInsets(top: vTopPadding, left: hPadding, bottom: vBotPadding, right: hPadding))
// set the label's frame
label.frame = labelRect
// position container view off-the-top of the screen
container.frame.origin.y = -container.frame.size.height
DispatchQueue.main.async {
UIView.animate(withDuration: 0.4, delay: 0.0, options: .curveLinear, animations: {
container.frame.origin.y = 0
}) { (finished) in
UIView.animate(withDuration: 0.4,delay: 2.0, options: .curveLinear, animations: {
container.frame.origin.y = -container.frame.size.height
})
}
}
}
我需要创建一个自定义下拉横幅,它会从顶部掉落,然后在几秒钟内上升。 对于自定义横幅 UIView,我指的是这个问题,这是一个完美的例子,这就是我想要的,因为我的横幅也是动态的,这将根据文本调整高度。
但不确定如何制作此动画。我已经为动画编写了代码并且它工作得很好但不确定这个动画如何与我上面提到的自定义视图一起工作。
@IBAction func buttonClicked(_ sender: Any) {
bannerView()
}
func bannerView() {
let container = UIView()
container.backgroundColor = UIColor.black
container.frame = CGRect(x: 0, y: -200, width: self.view.frame.width, height: 200)
UIApplication.shared.windows[0].addSubview(container)
DispatchQueue.main.async {
UIView.animate(withDuration: 0.4, delay: 0.0, options: .curveLinear, animations: {
container.frame = CGRect(x:0, y: 0, width: self.view.frame.size.width, height: 200)
}) { (finished) in
UIView.animate(withDuration: 0.4,delay: 2.0, options: .curveLinear, animations: {
container.frame = CGRect(x:0, y: -200, width: self.view.frame.size.width, height: 200)
})
}
}
}
@IBAction func buttonClicked(_ sender: Any) {
var stringText = "Lorem ipsum dolor sit amet,"
bannerNotification(text: stringText)
}
func bannerNotification(text: String) {
let container = UIView()
let image = UIImageView()
let label = UILabel()
container.frame = CGRect(x: 0, y:-100, width: self.view.frame.size.width, height: 100)
container.backgroundColor = .blue
image.frame = CGRect(x: 15, y: 60, width: 30, height: 30)
image.image = UIImage(named: "passport")
label.frame = CGRect(x: image.bounds.maxX + 35, y: 40, width: container.frame.size.width - 100, height: 50)
label.numberOfLines = 0
label.font = UIFont(name:"Helvetica Neue", size: 15)
label.text = text
container.addSubview(image)
container.addSubview(label)
UIApplication.shared.windows[0].addSubview(container)
DispatchQueue.main.async {
UIView.animate(withDuration: 0.4, delay: 0.0, options: .curveLinear, animations: {
container.frame = CGRect(x:0, y: 0, width: self.view.frame.size.width, height: 100)
}) { (finished) in
UIView.animate(withDuration: 0.4,delay: 2.0, options: .curveLinear, animations: {
container.frame = CGRect(x:0, y: -100, width: self.view.frame.size.width, height: 100)
})
}
}
}
试试这个,希望对你有用。
我不喜欢将子视图添加到 windows 而不是添加到视图层次结构...但是,如果这确实是您想要做的,请尝试一下(查看代码中的注释).
@IBAction func buttonClicked(_ sender: Any) {
bannerNotification(text: "Banner Test with lots of text to wrap onto multiple lines. We're using explict frames and calculating the height of the (potentially multiline) label.")
}
func bannerNotification(text: String){
// create a "container" view
let container = UIView()
// create a label
let label = UILabel()
// add label to container
container.addSubview(label)
// color / font / text properties as desired
container.backgroundColor = UIColor(red: 0.0, green: 0.5, blue: 1.0, alpha: 1.0)
label.backgroundColor = .yellow
label.numberOfLines = 0
label.font = UIFont(name:"Helvetica Neue", size: 16.0)
label.text = text
// padding on left/right of label
let hPadding: CGFloat = 16.0
// padding on top of label - account for status bar?
let vTopPadding: CGFloat = 32.0
// padding on bottom of label
let vBotPadding: CGFloat = 16.0
let width = UIScreen.main.bounds.width
// get reference to window 0
let w = UIApplication.shared.windows[0]
// add container to window
w.addSubview(container)
// calculate label height
let labelSize = label.systemLayoutSizeFitting(CGSize(width: width - (hPadding * 2.0),
height: UIView.layoutFittingCompressedSize.height))
// rect for container view - start with .zero
var containerRect = CGRect.zero
// set its size to screen width x calculated label height + top/bottom padding
containerRect.size = CGSize(width: width, height: labelSize.height + vTopPadding + vBotPadding)
// set container view's frame
container.frame = containerRect
// rect for label - container rect inset by padding values
let labelRect = containerRect.inset(by: UIEdgeInsets(top: vTopPadding, left: hPadding, bottom: vBotPadding, right: hPadding))
// set the label's frame
label.frame = labelRect
// position container view off-the-top of the screen
container.frame.origin.y = -container.frame.size.height
DispatchQueue.main.async {
UIView.animate(withDuration: 0.4, delay: 0.0, options: .curveLinear, animations: {
container.frame.origin.y = 0
}) { (finished) in
UIView.animate(withDuration: 0.4,delay: 2.0, options: .curveLinear, animations: {
container.frame.origin.y = -container.frame.size.height
})
}
}
}