iOS - 如何在没有第三方框架的情况下在 Swift 中创建自定义动画横幅

Posted

技术标签:

【中文标题】iOS - 如何在没有第三方框架的情况下在 Swift 中创建自定义动画横幅【英文标题】:iOS - How to create custom animated banner without third party framework in Swift 【发布时间】:2020-09-03 18:17:09 【问题描述】:

我需要创建一个自定义下拉横幅,该横幅将从顶部下降,然后在几秒钟内上升。 对于自定义横幅 UIView,我指的是这个问题,这是一个完美的例子,这就是我想要的,因为我的横幅也是动态的,这将根据文本调整高度。

Swift - How to set custom view by text length

但不确定如何制作动画。我已经为动画编写了一段代码,它可以完美地工作,但不确定这个动画将如何与我上面提到的自定义视图一起工作。

@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)
            )
        
    

【问题讨论】:

你试过了吗? 是的,我试过了,但没有用。 :( 您知道这将如何协同工作吗?带导航的自定义横幅? @DonMag 不完全清楚你在做什么。您提到 "navigation" ...您是否尝试在使用 UINavigationController 时显示向下滑动并覆盖导航栏的视图? 我很抱歉,我正在尝试编写带有动画的自定义横幅,是的,正确.. 此视图将从具有 UINavigationBar 的屏幕顶部向下滑动。所以基本上这将是用户的成功或失败通知横幅,但动态。 @DonMag 【参考方案1】:

我不喜欢将子视图添加到窗口而不是视图层次结构...但是,如果这确实是您想要做的,请尝试一下(查看代码中的 cmets)。

@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
            )
        
    
    

【讨论】:

【参考方案2】:
@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)
            )
        
    

试试这个,希望对你有用。

【讨论】:

@DonMag 你认为这有什么帮助? 是的,这是有效的,但不适用于长文本。 @DonMag

以上是关于iOS - 如何在没有第三方框架的情况下在 Swift 中创建自定义动画横幅的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有第三方服务的情况下在开发过程中为 webhook 公开本地服务器?

如何在没有任何第三方模块的情况下在 Node Js 中发布 https 帖子?

如何在没有真实设备的情况下在 iOS 上测试推送通知?

如何在没有遍历框架的情况下在neo4j中进行深度优先遍历?

如何在没有实体框架提供程序的情况下在 .net 核心中实现谷歌登录

如何在没有用户交互的情况下在后台接收 iOS 通知