Swift:在视图上覆盖带有文本的矩形

Swift: Overlay rectangle with text over view

如果我们的应用出现网络连接错误,我们希望在屏幕顶部覆盖一个彩色透明矩形,其中包含一些 "Network not available" 之类的文本。矩形应覆盖屏幕的整个宽度,高度应足以显示文本。我们将使用计时器来仅在短时间内显示矩形。你怎么能这样做?

实际视图可能是 UITableViewController、UIViewController 或其他...

我完成叠加的方法是将新的 UIViewController 拖到故事板中,然后将 UIView 拖到其中。在布置 UI 时,将 UIViewController 的背景色设为黑色会很有帮助。在 UIView 中完成元素布局后,将 UIViewController 的背景颜色更改为透明。

这是配置文件覆盖的示例:

在这种情况下,我实际上将 UIViewController 背景设为灰色,alpha 约为 50%。然后,当我使用淡入淡出过渡呈现此视图控制器时,它看起来像是出现在当前上下文的顶部:

func showOverlay() {
    //
    guard let vc = UIStoryboard(name: "MyStoryboard", bundle: nil).instantiateViewController(withIdentifier: "myOverlay") as? UIViewController else {
        print("failed to get myOverlay from MyStoryboard")
        return
    }

    vc.modalPresentationStyle = .overCurrentContext
    vc.modalTransitionStyle = .crossDissolve

    self.present(vc, animated: true, completion: {
        // after 3 seconds, dismiss the overlay
        dispatchAfterSeconds(3) {
            vc.dismiss(animated: true)
        }
    })
}

这使用了一个方便的函数,dispatchAfterSeconds:

// execute function after delay using GCD
func dispatchAfterSeconds(_ seconds: Double, completion: @escaping (() -> Void)) {
    let triggerTime = Int64(Double(NSEC_PER_SEC) * seconds)
    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(triggerTime) / Double(NSEC_PER_SEC), execute: { () -> Void in
        completion()
    })
}

请注意,当我谈到更改 UIViewController 的背景颜色时,我的实际意思是在 UIViewController 中默认创建的视图的背景颜色在故事板中创建。

你可以这样做:

let deadlineTime = DispatchTime.now() + .seconds(2)

let window = UIApplication.shared.keyWindow!

let rectangleView = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: 20))
rectangleView.backgroundColor = UIColor.red

let label = UILabel(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: 20))
label.text = "Network not available"

rectangleView.addSubview(label)

window.addSubview(rectangleView)

DispatchQueue.main.asyncAfter(deadline: deadlineTime) {
    rectangleView.removeFromSuperview()
}