小编Dar*_*rko的帖子

看到iPhone X Simulator顶部和底部的黑条

在iPhone X模拟器(GM Seed)中运行我的应用程序我注意到两个奇怪的效果:

  • 应用程序不使用全屏空间(顶部和底部区域为黑色)
  • 标题栏下面有一个奇怪的白条

在此输入图像描述

有谁知道这里发生了什么以及如何解决这个问题?我在Interface Builder中找不到任何新设置.

uinavigationbar ios ios-simulator xcode9 iphone-x

124
推荐指数
6
解决办法
4万
查看次数

SwiftUI - 如何避免导航硬编码到视图中?

我尝试为更大的、可用于生产的 SwiftUI 应用程序构建架构。我一直在遇到同样的问题,这指向 SwiftUI 中的一个主要设计缺陷。

仍然没有人能给我一个完整的工作,生产就绪的答案。

如何做SwiftUI包含导航的可重用视图?

由于它SwiftUI NavigationLink与视图有很强的联系,这根本不可能以这样的方式在更大的应用程序中扩展。NavigationLink在那些小样本应用程序中,是的 - 但不是当您想在一个应用程序中重用许多视图时。也可能在模块边界上重用。(例如:在 iOS、WatchOS 等中重用 View...)

设计问题:导航链接被硬编码到视图中。

NavigationLink(destination: MyCustomView(item: item))
Run Code Online (Sandbox Code Playgroud)

但是如果包含这个的视图NavigationLink应该是可重用的,我就不能对目的地进行硬编码。必须有一种机制来提供目的地。我在这里问了这个问题并得到了很好的答案,但仍然不是完整的答案:

SwiftUI MVVM 协调器/路由器/导航链接

这个想法是将目标链接注入可重用视图。一般来说,这个想法可行,但不幸的是,这并不能扩展到真正的生产应用程序。一旦我有多个可重用的屏幕,我就会遇到一个逻辑问题,即一个可重用的视图 ( ViewA) 需要一个预配置的视图目标 ( ViewB)。但是如果ViewB还需要一个预配置的 view-destinationViewC呢?我需要建立ViewB在这样的方式已经ViewC被注入已经ViewB在我注入ViewBViewA。等等......但由于当时必须传递的数据不可用,整个构造失败。

我的另一个想法是使用Environmentas 依赖注入机制为NavigationLink. 但我认为这或多或少应该被视为一种黑客行为,而不是大型应用程序的可扩展解决方案。我们最终会基本上将环境用于所有事情。但是因为 Environment 也只能在 View 内部使用(而不是在单独的 Coordinators 或 ViewModels 中),所以在我看来这将再次创建奇怪的构造。

就像业务逻辑(例如视图模型代码)和视图必须分开,导航和视图也必须分开(例如协调器模式)UIKit因为我们访问视图UIViewControllerUINavigationController …

xcode ios swift swiftui swiftui-navigationlink

109
推荐指数
6
解决办法
8034
查看次数

iOS 11自定义导航栏中的搜索栏

我想在iOS 11搜索栏中嵌入导航栏时更改文本和图标的颜色.所以占位符文本,搜索文本和搜索图标.

在此输入图像描述

if #available(iOS 11.0, *) {
    navigationController?.navigationBar.prefersLargeTitles = false
    let searchController = UISearchController(searchResultsController: nil)
    navigationItem.searchController = searchController
    navigationItem.hidesSearchBarWhenScrolling = false

    searchController.searchBar.placeholder = "Suchen"
    searchController.searchBar.tintColor = .white
}
Run Code Online (Sandbox Code Playgroud)

正如您在图像中看到的那样,文本在深蓝色背景上呈灰色,看起来很难看.我希望文字和图标至少是白色的.(改变蓝色背景颜色也行不通,请看我的其他问题)

唯一有效的方法是改变闪烁光标的颜色和"取消"按钮,这是通过.tintColor属性完成的.

似乎在iOS 10及以下版本中工作的解决方案在iOS 11中似乎不再起作用,因此请仅发布您在iOS 11中工作的解决方案.谢谢.

也许我错过了iOS 11中关于这种"自动样式"的观点.任何帮助都表示赞赏.

uinavigationbar uisearchbar ios swift

45
推荐指数
1
解决办法
3万
查看次数

UINavigationBar中的iOS 11 UISearchBar

我想在新的导航栏中放置一个搜索栏,其中包含新的iOS 11大标题.但是,搜索栏的颜色会自动由iOS应用,我无法更改它.

if #available(iOS 11.0, *) {
    let sc = UISearchController(searchResultsController: nil)
    navigationItem.searchController = sc
    navigationItem.hidesSearchBarWhenScrolling = false
}
Run Code Online (Sandbox Code Playgroud)

搜索栏是深蓝色背景,但我只想将其更改为白色.

在此输入图像描述

设置背景颜色会导致:

navigationItem.searchController?.searchBar.backgroundColor = UIColor.white
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我也试过setScopeBarButtonBackgroundImagesetBackgroundImage在搜索栏上但是一切看起来都很奇怪.

此外,当我通过点击搜索栏触发搜索时,它会切换到右侧有取消按钮的模式.("Abbrechen"德文)

在此输入图像描述

并且"Abbrechen"文本颜色也无法更改.(需要它也是白色的)

任何帮助表示赞赏.

编辑:根据要求,这里是导航栏样式的代码:

self.navigationBar.tintColor = UIColor.myWhite
self.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor : UIColor.myWhite, NSAttributedStringKey.font: UIFont.myNavigationBarTitle()]
self.navigationBar.barTintColor = UIColor.myTint

if #available(iOS 11.0, *) {
    self.navigationBar.prefersLargeTitles = true
    self.navigationBar.largeTitleTextAttributes = [NSAttributedStringKey.foregroundColor : UIColor.myWhite, NSAttributedStringKey.font: UIFont.myNavigationBarLargeTitle()]
}
Run Code Online (Sandbox Code Playgroud)

目前的结果:我使用Krunals的想法来设置搜索栏背景的颜色,但圆角丢失了.重新设置圆角后,搜索栏的动画似乎被打破.

在此输入图像描述

所以仍然没有令人满意的解 似乎嵌入到iOS 11导航栏中的搜索栏无法自定义.同时,仅仅改变占位符文本的颜色就足够了,但即使这样也不可能.(我尝试过StackOverflow的多种方法 - 不起作用)

uinavigationbar uisearchbar ios swift ios11

21
推荐指数
1
解决办法
1万
查看次数

Swift运算符和nil

这种行为有什么解释?

let x: Int? = nil
if x < 10 {
    print("x < 10")
}
Run Code Online (Sandbox Code Playgroud)

它打印"x <10".这不应该产生运行时错误或至少是编译器警告吗?

编辑:

我向Apple提交了一份错误报告,他们承认这是另一份报告的现有副本.所以这将由Apple以某种方式处理/修复.

swift

14
推荐指数
1
解决办法
357
查看次数

导航栏中的iOS 11 UISearchBar

UISearchBar在iOS 11中的行为与iOS 10及以下版本不同.

  • 大小已经改变
  • 当按下另一个受控视图时,淡出动画将丢失

我用这个代码以某种方式"修复"了大小:

if #available(iOS 11.0, *) {
    searchBar.heightAnchor.constraint(equalToConstant: 44).isActive = true
}
Run Code Online (Sandbox Code Playgroud)

但我无法修复动画.任何想法,除了手动推动搜索栏动画?

UIView.animate(withDuration: 0.3, animations: { [weak self] in
    guard let strongSelf = self else { return }
    strongSelf.searchBar.alpha = 0.0
})
Run Code Online (Sandbox Code Playgroud)

在此处查看损坏的动画效果的视频.

uinavigationbar uisearchbar ios swift ios11

10
推荐指数
1
解决办法
5016
查看次数

SwiftUI UIHostingController 导航标题动画损坏

当我使用 UIHostingController 将新的 SwiftUI.View 推送到现有 UIKit UIViewController 的导航堆栈时,导航栏中标题的动画被破坏。我在 Xcode 12.0 中在一个全新的项目上进行了测试。

仔细观察标题“UIHostingController”。您可以看到该动画与普通的推送动画有何不同,它只是凭空“出现”,看起来很破碎。第二个动画已经从 SwiftUI.NavigationLink 中发生,看起来不错。

如果您想尝试一下,这里是示例项目的链接: https://www.dropbox.com/s/mjkuzhpsb6yvlir/HostingControllerTest.zip ?dl=0

请参阅此 GIF 图像:(如果您看不到 GIF 动画,请在另一个浏览器选项卡中打开)

这是背后的代码:

class ViewController: UIViewController {
    private let button = UIButton(frame: .zero)

    override func viewDidLoad() {
        super.viewDidLoad()
        self.title = "UIHostingController Title Test"
        self.view.backgroundColor = UIColor.white
        
        self.view.addSubview(self.button)
        button.translatesAutoresizingMaskIntoConstraints = false
        button.setTitle("Push UIHostingController", for: .normal)
        button.addTarget(self, action: #selector(Self.pushVC), for: .touchUpInside)
        button.setTitleColor(.blue, for: .normal)
        
        NSLayoutConstraint.activate([
            button.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            button.centerYAnchor.constraint(equalTo: self.view.centerYAnchor),
            button.widthAnchor.constraint(equalTo: self.view.widthAnchor),
            button.heightAnchor.constraint(equalToConstant: 50)
        ])
    }
    
    @objc private func pushVC() {
        let vc …
Run Code Online (Sandbox Code Playgroud)

xcode ios swift swiftui uihostingcontroller

7
推荐指数
1
解决办法
2452
查看次数

SwiftUI MVVM 协调器/路由器/导航链接

我在将 UIKit 架构模式转换为 SwiftUI 时遇到问题。我目前的模式主要是带有协调器/路由器的 MVVM。添加@ObservableObject/@Published 后,MVVM 部分看起来非常简单和自然。但是协调/路由似乎不直观。视图和协调(导航)功能在 SwiftUI 中紧密耦合。似乎不可能将它们与使用 helper struct 分开AnyView

这是一个示例:我想在 SwiftUI 中创建一个可重用的行/单元格。假设生产中的这一行非常复杂,因此我想重用它。我也想把它放在另一个模块中,这样我就可以在多个目标中重用它。(如 iOS、macCatalyst 等...)

在此处输入图片说明

现在我想控制当用户点击该视图或该视图中的按钮时会发生什么。根据上下文,我需要导航到不同的目的地。据我所知,可能的 NavigationLink 目标要么硬连线到视图中,要么AnyView传递到视图中。

这里有一些示例代码。此单元格/行包含两个按钮。我想导航到其他一些取决于上下文的视图,而不是硬连接到代码中:

struct ProductFamilyRow: View {
    @State private var selection: Int? = 0
    let item: ProductFamilyItem

    let destinationView1: AnyView
    let destinationView2: AnyView

    var body: some View {
        VStack {
            NavigationLink(
                destination: destinationView1,
                tag: 1,
                selection: self.$selection
            ) {
                EmptyView()
            }

            NavigationLink(
                destination: destinationView2,
                tag: 2,
                selection: self.$selection
            ) {
                EmptyView()
            }

            HStack {
                Text(item.title) …
Run Code Online (Sandbox Code Playgroud)

mvvm ios swift coordinator-pattern swiftui

6
推荐指数
1
解决办法
4172
查看次数

在异步网络请求中捕获自身弱或无主

每当我做异步网络请求时,可能是在请求到达时self已经是nil(例如,ViewController已被解除).

为了防止这种情况,我通常将自我视为弱者:

    future.onSuccess(context: Queue.main.context, callback: { [weak self] result in
        if let strongSelf = self {
            // Do some stuff with self, which is now guaranteed to be not nil
            // strongSelf.someMethod()
        }
    })
Run Code Online (Sandbox Code Playgroud)

或者我可以将自己视为无主:

    future.onSuccess(context: Queue.main.context, callback: { [unowned self] result in
            // Do some stuff with self
            // self.someMethod()
    })
Run Code Online (Sandbox Code Playgroud)

我不关心请求返回,因为当请求在ViewController已被解除的时间点返回时,我没有从请求中显示任何内容.所以我不想让关闭时自己"活着".

我现在的问题是 - 在这种情况下是否足以将自己视为无主?或者我必须一直做[弱自我]的零检查?如果在请求到达并且self已经为零时无主捕获的情况下会发生什么 - 闭包是否仍然存在且将执行并且将在访问nil时触发运行时错误?或者封闭也会与自己一起解除分配,请求会遇到"空白"?

或者在这种情况下我可以忘记弱者和无人物,因为当自我取消分配时,闭包也将被解除分配,因此在请求到达时没有访问nil的危险吗?

PS:我知道关于这个话题已经有很多问题 - 答案但是在我不关心异步到达的情况下我找不到答案.

closures asynchronous swift

5
推荐指数
2
解决办法
1633
查看次数

Swift Codable初始化

我想在Swift Coding / Encoding功能完成对JSON的解码后做一些初始化逻辑。

struct MyStruct: Codable {
    let id: Int 
    var name: String

    init() {
       name = "\(id) \(name)" 
    }
}
Run Code Online (Sandbox Code Playgroud)

但是我得到了编译器错误:

Return from initializer without initializing all stored properties
Run Code Online (Sandbox Code Playgroud)

这对我很清楚,因为init()希望我初始化所有属性。但是添加具有所有必需属性的init()并不能解决该问题,因为当Codable插入时,此初始化器不会被调用(!):

init(id: Int, name: String) {
    // This initializer is not called if Decoded from JSON!
    self.id = id 
    self.name = "\(id) \(name)" 
}
Run Code Online (Sandbox Code Playgroud)

然而,在解码完成之后,是否有一种方法可以执行一些初始化逻辑,而无需为每个属性手动进行所有解码?因此无需每次都执行init(from decoder: Decoder)。在这个简短的示例中,我只有两个简单的属性,但是生产代码包含数千个属性。

谢谢。

json swift codable decodable

5
推荐指数
2
解决办法
8106
查看次数

使用URL方案(深层链接)调用Xcode 9.3构建崩溃

在Xcode 9.3中,当我尝试通过URL方案(deeplink)打开它时,我的应用程序崩溃,如: myapp://somepath

Xcode 9.2没问题.我安装了两个Xcode版本,与Xcode 9.3完全相同的代码崩溃,但Xcode 9.2没有.崩溃发生呼叫到达之前:

AppDelegate.application(UIApplication, open : URL, sourceApplication : String?, annotation : Any) -> Bool
Run Code Online (Sandbox Code Playgroud)

我在这个函数中设置了一个断点,它永远不会到达它,它只是崩溃了.这里的崩溃日志:

http://crashes.to/s/3237f00bf6a

那么任何想法导致这个或如何解决它?

xcode ios swift

3
推荐指数
1
解决办法
746
查看次数