AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / coding / 问题 / 77607444
Accepted
Duncan C
Duncan C
Asked: 2023-12-05 23:38:35 +0800 CST2023-12-05 23:38:35 +0800 CST 2023-12-05 23:38:35 +0800 CST

UIAlertController 的空子类可以安全地与“appearance(whenContainedInInstancesOf:)”一起使用

  • 772

有人想改变UIAlertAction特定按钮的行为UIAlertController,但不想改变其他按钮的行为。(他们想要一个警报的多行按钮标签,但所有其他警报的正常行为。)(这是另一个问题的链接。)

如果您阅读文档,UIAlertController它会说

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

作为一个实验,我决定尝试创建一个虚拟的空子类UIAlertController,纯粹是为了给 UIAppearance 方法提供一个类名appearance(whenContainedInInstancesOf:)

虚拟子类的定义如下:

class FooController: UIAlertController {
}

然后我可以使用这个语句

        UILabel.appearance(whenContainedInInstancesOf: [FooController.self]).numberOfLines = 2

UILabel并特别在以下实例中覆盖 s 的出现FooController

它有效,看起来完美无缺。

您可以在此处从 Github 下载示例项目。

当您创建 vanilla 时UIAlertController,它的UIAlertAction按钮像平常一样具有单行标签。当您创建 时FooController,它的UIAlertAction按钮具有多行标签。

虽然它看起来工作得很好,但我对反对苹果文档中明确的声明而不是子类化持怀疑态度UIAlertController。

忽略该警告并使用空子类有哪些风险?

这是我的示例项目中的代码供参考:

import UIKit

class FooController: UIAlertController {
}

class ViewController: UIViewController {
    
    let buttonLabels = [
    """
    Button1
    line2
    """,
    """
    Button2
    line2
    """,
    """
    Button3
    line2
    """
    ]

    @IBAction func handleAlertButton(_ sender: Any) {
        presentAlert(type: UIAlertController.self)
    }
    
    @IBAction func handleFooButton(_ sender: Any) {
        presentAlert(type: FooController.self)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        UILabel.appearance(whenContainedInInstancesOf: [FooController.self]).numberOfLines = 2
    }
    
    func presentAlert(type: UIAlertController.Type) {
        let sheet = type.init(title: type.description(), message: nil, preferredStyle: .actionSheet)
        for buttonTitle in buttonLabels {
            let item = UIAlertAction(title: buttonTitle, style: .default) { (action) in
                print("Button \(buttonTitle) tapped")
            }
            sheet.addAction(item)
        }
        present(sheet, animated: true, completion: nil)
    }
}
  • 1 1 个回答
  • 28 Views

1 个回答

  • Voted
  1. Best Answer
    HangarRash
    2023-12-06T01:22:57+08:002023-12-06T01:22:57+08:00

    忽略该警告并使用空子类有哪些风险?

    1. 苹果可能会拒绝该应用程序。
    2. UIAlertController在 iOS 的未来更新中可能无法正常运行。
    3. UILabel.appearance子类的具体原因(使用)可能在 iOS 的未来更新中无法正常运行。

    这些都是可能存在的风险。

    虽然 Apple 始终拥有最终决定权,但 Apple 不太可能仅仅因为您UIAlertController以这种方式进行子类化而拒绝应用程序。我个人对几个 Apple 认为不应该进行子类化的 UIKit 类进行了子类化。我在一个应用程序中完成了此操作,该应用程序已在应用程序商店中存在多年并且已经进行了多次更新。您没有使用任何私有 API。Apple 并没有说你不能子类化UIAlertController。它表示该类不打算被子类化。

    这会导致风险#2。Apple 声明UIAlertController不打算对其进行子类化,也不支持子类化。这意味着它不提供任何可覆盖或修改的 API。但这并不意味着您不能对其进行子类化以添加辅助方法等。或者只是给类一个新名称,以便您可以执行类似UILabel.appearance. 您的子类是良性的,不会尝试修改功能或深入研究私有子视图结构。它是一个“安全”子类,不会破坏任何现有功能。

    最后,风险#3。虽然很小,但这可能是 3 中“最大”的风险。Apple 可能会在未来的 iOS 更新中进行任意数量的更改,这可能会阻碍或破坏在子类上UIAlertController使用的预期结果。UILabel.appearance在每个 iOS 版本上测试代码是谨慎的做法。最坏的情况可能是“黑客”将停止工作。

    • 1

相关问题

  • 将复制活动的序列号添加到 Blob

  • Packer 动态源重复工件

  • 选择每组连续 1 的行

  • 图形 API 调用列表 subscribedSkus 状态权限不足,但已授予权限

  • 根据列值创建单独的 DF 的函数

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    使用 <font color="#xxx"> 突出显示 html 中的代码

    • 2 个回答
  • Marko Smith

    为什么在传递 {} 时重载解析更喜欢 std::nullptr_t 而不是类?

    • 1 个回答
  • Marko Smith

    您可以使用花括号初始化列表作为(默认)模板参数吗?

    • 2 个回答
  • Marko Smith

    为什么列表推导式在内部创建一个函数?

    • 1 个回答
  • Marko Smith

    我正在尝试仅使用海龟随机和数学模块来制作吃豆人游戏

    • 1 个回答
  • Marko Smith

    java.lang.NoSuchMethodError: 'void org.openqa.selenium.remote.http.ClientConfig.<init>(java.net.URI, java.time.Duration, java.time.Duratio

    • 3 个回答
  • Marko Smith

    为什么 'char -> int' 是提升,而 'char -> Short' 是转换(但不是提升)?

    • 4 个回答
  • Marko Smith

    为什么库中不调用全局变量的构造函数?

    • 1 个回答
  • Marko Smith

    std::common_reference_with 在元组上的行为不一致。哪个是对的?

    • 1 个回答
  • Marko Smith

    C++17 中 std::byte 只能按位运算?

    • 1 个回答
  • Martin Hope
    fbrereto 为什么在传递 {} 时重载解析更喜欢 std::nullptr_t 而不是类? 2023-12-21 00:31:04 +0800 CST
  • Martin Hope
    比尔盖子 您可以使用花括号初始化列表作为(默认)模板参数吗? 2023-12-17 10:02:06 +0800 CST
  • Martin Hope
    Amir reza Riahi 为什么列表推导式在内部创建一个函数? 2023-11-16 20:53:19 +0800 CST
  • Martin Hope
    Michael A fmt 格式 %H:%M:%S 不带小数 2023-11-11 01:13:05 +0800 CST
  • Martin Hope
    God I Hate Python C++20 的 std::views::filter 未正确过滤视图 2023-08-27 18:40:35 +0800 CST
  • Martin Hope
    LiDa Cute 为什么 'char -> int' 是提升,而 'char -> Short' 是转换(但不是提升)? 2023-08-24 20:46:59 +0800 CST
  • Martin Hope
    jabaa 为什么库中不调用全局变量的构造函数? 2023-08-18 07:15:20 +0800 CST
  • Martin Hope
    Panagiotis Syskakis std::common_reference_with 在元组上的行为不一致。哪个是对的? 2023-08-17 21:24:06 +0800 CST
  • Martin Hope
    Alex Guteniev 为什么编译器在这里错过矢量化? 2023-08-17 18:58:07 +0800 CST
  • Martin Hope
    wimalopaan C++17 中 std::byte 只能按位运算? 2023-08-17 17:13:58 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve