在iPhone X模拟器(GM Seed)中运行我的应用程序我注意到两个奇怪的效果:
有谁知道这里发生了什么以及如何解决这个问题?我在Interface Builder中找不到任何新设置.
我尝试为更大的、可用于生产的 SwiftUI 应用程序构建架构。我一直在遇到同样的问题,这指向 SwiftUI 中的一个主要设计缺陷。
仍然没有人能给我一个完整的工作,生产就绪的答案。
如何做SwiftUI包含导航的可重用视图?
由于它SwiftUI NavigationLink与视图有很强的联系,这根本不可能以这样的方式在更大的应用程序中扩展。NavigationLink在那些小样本应用程序中,是的 - 但不是当您想在一个应用程序中重用许多视图时。也可能在模块边界上重用。(例如:在 iOS、WatchOS 等中重用 View...)
设计问题:导航链接被硬编码到视图中。
NavigationLink(destination: MyCustomView(item: item))
Run Code Online (Sandbox Code Playgroud)
但是如果包含这个的视图NavigationLink应该是可重用的,我就不能对目的地进行硬编码。必须有一种机制来提供目的地。我在这里问了这个问题并得到了很好的答案,但仍然不是完整的答案:
这个想法是将目标链接注入可重用视图。一般来说,这个想法可行,但不幸的是,这并不能扩展到真正的生产应用程序。一旦我有多个可重用的屏幕,我就会遇到一个逻辑问题,即一个可重用的视图 ( ViewA) 需要一个预配置的视图目标 ( ViewB)。但是如果ViewB还需要一个预配置的 view-destinationViewC呢?我需要建立ViewB在这样的方式已经ViewC被注入已经ViewB在我注入ViewB到ViewA。等等......但由于当时必须传递的数据不可用,整个构造失败。
我的另一个想法是使用Environmentas 依赖注入机制为NavigationLink. 但我认为这或多或少应该被视为一种黑客行为,而不是大型应用程序的可扩展解决方案。我们最终会基本上将环境用于所有事情。但是因为 Environment 也只能在 View 内部使用(而不是在单独的 Coordinators 或 ViewModels 中),所以在我看来这将再次创建奇怪的构造。
就像业务逻辑(例如视图模型代码)和视图必须分开,导航和视图也必须分开(例如协调器模式)UIKit因为我们访问视图UIViewController和UINavigationController …
我想在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中关于这种"自动样式"的观点.任何帮助都表示赞赏.
我想在新的导航栏中放置一个搜索栏,其中包含新的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)
我也试过setScopeBarButtonBackgroundImage并setBackgroundImage在搜索栏上但是一切看起来都很奇怪.
此外,当我通过点击搜索栏触发搜索时,它会切换到右侧有取消按钮的模式.("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的多种方法 - 不起作用)
这种行为有什么解释?
let x: Int? = nil
if x < 10 {
print("x < 10")
}
Run Code Online (Sandbox Code Playgroud)
它打印"x <10".这不应该产生运行时错误或至少是编译器警告吗?
编辑:
我向Apple提交了一份错误报告,他们承认这是另一份报告的现有副本.所以这将由Apple以某种方式处理/修复.
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)
在此处查看损坏的动画效果的视频.
当我使用 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) 我在将 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) 每当我做异步网络请求时,可能是在请求到达时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:我知道关于这个话题已经有很多问题 - 答案但是在我不关心异步到达的情况下我找不到答案.
我想在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)。在这个简短的示例中,我只有两个简单的属性,但是生产代码包含数千个属性。
谢谢。
在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
那么任何想法导致这个或如何解决它?