没有模糊视图效果的 UIAlertController 操作表

man*_*oon 5 objective-c ios swift uialertcontroller uivisualeffectview

我正在用于UIAlertController一些操作。

但我不太喜欢动作组视图中的模糊视图效果(请参见下面的屏幕截图)。

具有模糊视图的操作表

我正在尝试消除这种模糊效果。我在网上做了一些研究,但找不到任何UIAlertController可以消除这种模糊效果的 API。另外,根据他们的苹果文档:

UIAlertController 类旨在按原样使用,不支持子类化。此类的视图层次结构是私有的,不得修改。

我看到 Instagram 也消除了这种模糊的视图效果:

Instagram 的固定版本

我找到删除它的唯一方法是通过UIAlertController.

extension UIAlertController {
    @discardableResult private func findAndRemoveBlurEffect(currentView: UIView) -> Bool {
        for childView in currentView.subviews {
            if childView is UIVisualEffectView {
                childView.removeFromSuperview()
                return true
            } else if String(describing: type(of: childView.self)) == "_UIInterfaceActionGroupHeaderScrollView" {
                // One background view is broken, we need to make sure it's white.
                if let brokenBackgroundView = childView.superview {
                    // Set broken brackground view to a darker white
                    brokenBackgroundView.backgroundColor = UIColor.colorRGB(red: 235, green: 235, blue: 235, alpha: 1)
                }
            }
            findAndRemoveBlurEffect(currentView: childView)
        }
        return false
    }
}

let actionSheetController = UIAlertController(title: title, message: nil, preferredStyle: .actionSheet)
actionSheetController.view.tintColor = .lightBlue
actionSheetController.removeBlurryView()
Run Code Online (Sandbox Code Playgroud)

这工作得很好,它消除了我的模糊视图效果:

固定动作表

我想知道......我的解决方案是实现这一目标的唯一方法吗?或者我对警报控制器的外观缺少一些东西?也许有一种更干净的方法来实现这个结果?还有其他想法吗?

Vad*_*rov 3

子类化更容易UIAlertController

viewDidLayoutSubviews这个想法是每次调用时遍历视图层次结构,删除 的效果UIVisualEffectView并更新它们backgroundColor

class AlertController: UIAlertController {

    /// Buttons background color.
    var buttonBackgroundColor: UIColor = .darkGray {
        didSet {
            // Invalidate current colors on change.
            view.setNeedsLayout()
        }
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()

        // Traverse view hierarchy.
        view.allViews.forEach {
            // If there was any non-clear background color, update to custom background.
            if let color = $0.backgroundColor, color != .clear {
                $0.backgroundColor = buttonBackgroundColor
            }
            // If view is UIVisualEffectView, remove it's effect and customise color.
            if let visualEffectView = $0 as? UIVisualEffectView {
                visualEffectView.effect = nil
                visualEffectView.backgroundColor = buttonBackgroundColor
            }
        }

        // Update background color of popoverPresentationController (for iPads).
        popoverPresentationController?.backgroundColor = buttonBackgroundColor
    }

}


extension UIView {

    /// All child subviews in view hierarchy plus self.
    fileprivate var allViews: [UIView] {
        var views = [self]
        subviews.forEach {
            views.append(contentsOf: $0.allViews)
        }

        return views
    }

}
Run Code Online (Sandbox Code Playgroud)

用法:

  1. 创建警报控制器。
  2. 设置按钮背景颜色: alertController.buttonBackgroundColor = .darkGray
  3. 定制并呈现控制器。

结果:

结果截图