iOS 标签在 viewWillAppear 期间不可见,从推送的视图控制器返回

问题描述 投票:0回答:1

我有一个带有 2 个图标和一个标签的按钮。对于 .selected 状态,该按钮具有不同的背景颜色。当我单击按钮时,会选择该按钮并推送一个新的 ViewController。我试图模仿 UITableViewCell.setSelected(animated:) 的行为,因此当用户从新的 ViewController 退出时,我希望背景颜色具有动画效果。我用这个:

UIView.transition(带有:按钮,持续时间:0.3,选项:.transitionCrossDissolve){button.isSelected = false}

当我将其放入 viewDidAppear 中时效果很好,但有点太晚了,所以我希望将其放入 viewWillAppear 中。问题是当我从 viewDidAppear 执行此操作时,按钮上的标签开始是透明的。图标精美且静态,但标签将从透明动画变为其颜色。为什么?我怎样才能防止这种情况发生?

这是一个小演示:

import UIKit

class ViewController: UIViewController {
    var myButton: MyButton?

    override func viewDidLoad() {
        super.viewDidLoad()
        myButton = MyButton()
        view.addSubview(myButton!)
        myButton?.frame.origin.x = 200
        myButton?.frame.origin.y = 200
        myButton?.addAction(.init { [weak self] _ in
            self?.myButton?.isSelected = true
            self?.navigationController?.pushViewController(ViewController2(), animated: true)
        }, for: .touchUpInside)
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        UIView.transition(with: myButton!, duration: 3, options: .transitionCrossDissolve) { self.myButton!.isSelected = false }

    }
    
//    override func viewDidAppear(_ animated: Bool) {
//        super.viewDidAppear(animated)
//        UIView.transition(with: myButton!, duration: 3, options: .transitionCrossDissolve) { self.myButton!.isSelected = false }
//
//    }

}
class ViewController2: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
    }
    
}

class MyButton: UIButton {
    
    let label = UILabel("Hahahaha", font: .systemFont(ofSize: 14), textColor: .black)

    convenience init() {
        self.init(frame: .init(x: 0, y: 0, width: 200, height: 200))
        
        setBackgroundColor(color: .white, forState: .normal)
        setBackgroundColor(color: .gray, forState: .highlighted)

        setBackgroundColor(color: .gray, forState: .selected)

        addSubview(label)
        label.frame.origin = .init(x: 40, y: 40)
        
        

    }
}

extension UIButton {
    func setBackgroundColor(color: UIColor, forState: UIControl.State) {
        self.clipsToBounds = true
        UIGraphicsBeginImageContext(CGSize(width: 1, height: 1))
        if let context = UIGraphicsGetCurrentContext() {
            context.setFillColor(color.cgColor)
            context.fill(CGRect(x: 0, y: 0, width: 1, height: 1))
            let colorImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            self.setBackgroundImage(colorImage, for: forState)
        }
    }
}

extension UILabel {
    convenience init(_ text: String = "", font: UIFont? = nil, textColor: UIColor? = .black) {
        self.init()
        self.text = text
        self.font = font
        sizeToFit()
        self.textColor = textColor
    }
}

尝试从 ViewController2 退出,看到标签开始不可见。现在注释掉 viewWillAppear 并使用 viewDidAppear 代替,标签从黑色开始。

ios swift uikit
1个回答
0
投票

解决方案:将标签的背景颜色设置为您想要的动画起始颜色。然后从内部触发动画

viewDidAppear

原因: 当按下按钮并启动导航时,该按钮不再突出显示,也不再被选中。这样它就恢复到正常状态了。

现在您导航回来。称为

viewWillAppear
。它的名字暗示“视图将在稍后显示,但它还不可见”。因此,当您此时启动动画时,UIKit 会假设即使它确实对某些内容进行了动画处理,用户也看不到它。 (视图还不可见 = 该视图上的动画也不会被看到。)为了节省资源,UIKit 将忽略动画。

所以解决方案是:尽早设置背景颜色,然后在调用

viewDidAppear
时启动动画,UIKit 会实际执行它。

© www.soinside.com 2019 - 2024. All rights reserved.