标签: swiftui

SwiftUI 中的 ObservedObject 和 StateObject 有什么区别

如果我ObservableObject在 SwiftUI 中有一个,我可以将其称为@ObservedObject

class ViewModel: ObservableObject {
    @Published var someText = "Hello World!"
}

struct ContentView: View {
    @ObservedObject var viewModel = ViewModel()
    
    var body: some View {
        Text(viewModel.someText)
    }
}
Run Code Online (Sandbox Code Playgroud)

或者作为@StateObject

class ViewModel: ObservableObject {
    @Published var someText = "Hello World!"
}

struct ContentView: View {
    @StateObject var viewModel = ViewModel()

    var body: some View {
        Text(viewModel.someText)
    }
}
Run Code Online (Sandbox Code Playgroud)

但两者之间的实际区别是什么?有没有一种情况比另一种更好,或者它们是两种完全不同的东西?

ios swift swiftui

56
推荐指数
5
解决办法
9285
查看次数

相当于在 Swift Combine 中使用 @Published 的计算属性?

在命令式 Swift 中,通常使用计算属性来提供对数据的便捷访问,而无需复制状态。

假设我有这个类用于命令式 MVC 使用:

class ImperativeUserManager {
    private(set) var currentUser: User? {
        didSet {
            if oldValue != currentUser {
                NotificationCenter.default.post(name: NSNotification.Name("userStateDidChange"), object: nil)
                // Observers that receive this notification might then check either currentUser or userIsLoggedIn for the latest state
            }
        }
    }

    var userIsLoggedIn: Bool {
        currentUser != nil
    }

    // ...
}
Run Code Online (Sandbox Code Playgroud)

如果我想使用Combine 创建一个反应式等效项,例如用于SwiftUI,我可以轻松添加@Published到存储的属性以生成Publishers,但不能用于计算属性。

    @Published var userIsLoggedIn: Bool { // Error: Property wrapper cannot be applied to a computed property
        currentUser != …
Run Code Online (Sandbox Code Playgroud)

ios swift reactive swiftui combine

55
推荐指数
3
解决办法
2万
查看次数

SwiftUI NavigationLink 立即加载目标视图,无需单击

使用以下代码:

struct HomeView: View {
    var body: some View {
        NavigationView {
            List(dataTypes) { dataType in
                NavigationLink(destination: AnotherView()) {
                    HomeViewRow(dataType: dataType)
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

奇怪的是,当HomeView出现时,NavigationLink立即加载AnotherView. 结果,所有AnotherView依赖项也被加载,即使它在屏幕上还不可见。用户必须单击该行才能使其出现。MyAnotherView包含一个DataSource,在那里发生各种事情。问题是此时DataSource已加载整体,包括一些计时器等。

难道我做错了什么..?如何以这种方式处理它,AnotherView一旦用户按下它就会加载HomeViewRow

ios swift swiftui

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

访问未安装在视图上的 StateObject 对象。这将每次创建一个新实例 - SwiftUI

每次应用程序启动时我都必须进行一些初始设置,但我收到错误:

在此输入图像描述

错误很明显,答案却不是。我尝试将 init 放入子视图中,但我不能,它需要位于 root 中@main。我是这样定义的:

@StateObject private var amplifyConfig: AmplifyConfig = AmplifyConfig()

init() {
    if(amplifyConfig.isAmplifyConfigured == false) {
        amplifyConfig.dataStoreHubEventSubscriber()
        amplifyConfig.configureAmplify()
    }
}
Run Code Online (Sandbox Code Playgroud)

我如何摆脱该警告并实际实现它,这样它就不会创建多个实例,这就是我使用 @EnvironmentObject 的原因?

swift swiftui

54
推荐指数
2
解决办法
3万
查看次数

SwiftUI NavigationView navigationBarTitle LayoutConstraints 问题

这可能与最近推出的新 (12.3) 版本的 XCode 相关,但我有一个非常简单的 SwiftUI 视图:

import SwiftUI

struct HomeView: View {
    var body: some View {
        NavigationView {
            Text("Text")
                .navigationBarTitle("My Title")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我在控制台中收到此警告:

2020-12-15 18:25:06.506062-0800 Shopmatic[46177:9585655] [LayoutConstraints] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and …
Run Code Online (Sandbox Code Playgroud)

ios swift swiftui

53
推荐指数
7
解决办法
6862
查看次数

如何为 AsyncImage 添加缓存

我是 SwiftUI 新手,正在研究如何从 URL 下载图像。我发现在 iOS15 中你可以使用 AsyncImage 来处理图像的所有阶段。代码如下所示。

    AsyncImage(url: URL(string: urlString)) { phase in
        switch phase {
        case .success(let image):
            image
                .someModifers
        case .empty:
            Image(systemName: "Placeholder Image")
                .someModifers
        case .failure(_):
            Image(systemName: "Error Image")
                .someModifers
        @unknown default:
            Image(systemName: "Placeholder Image")
                .someModifers
        }
    }
Run Code Online (Sandbox Code Playgroud)

我会启动我的应用程序,每次我在列表上上下滚动时,它都会再次下载图像。那么我怎样才能添加缓存呢?我试图像在 Swift 中那样添加缓存。像这样的东西。

struct DummyStruct {
  var imageCache = NSCache<NSString, UIImage>()
  func downloadImageFromURLString(_ urlString: String) {
    guard let url = URL(string: urlString) else { return }
    URLSession.shared.dataTask(with: url) { data, response, error in
        if let _ = …
Run Code Online (Sandbox Code Playgroud)

swift swiftui

49
推荐指数
4
解决办法
3万
查看次数

SwiftUI HStack以相等的间距填充整个宽度

我有一个 HStack:

struct BottomList: View {
    var body: some View {
        HStack() {
            ForEach(navData) { item in
                NavItem(image: item.icon, title: item.title)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如何以相等的间距将其内容完美地居中并自动填充整个宽度?

仅供参考,就像 Bootstraps CSS 类 .justify-content-around

ios swift swiftui

46
推荐指数
6
解决办法
2万
查看次数

SwiftUI:随机“调用中的额外参数”错误

所以我正在尝试学习 SwiftUI 和 Combine。我通常通过制作一个简单的小费计算器来开始新技术。

我似乎收到了一个随机的“通话中的额外参数”。编码时出错这是我的 SwiftUI 文件

import SwiftUI

internal enum ReceiptRowType {
    case subtotal
    case tax
    case total
    case tip
    case grandTotal
}

struct TipView: View {
    @ObservedObject internal var adBannerView: BannerAdView = BannerAdView()
    @ObservedObject internal var receiptViewModel: ReceiptViewModel

    private let percentageFormatter: NumberFormatter = {
        let f = NumberFormatter()
        f.numberStyle = .percent
        return f
    }()

    var body: some View {
        ZStack {
            Color.white
                .scaledToFit()

            VStack {
                if adBannerView.adHasLoaded {
                    adBannerView
                        .frame(maxHeight: adBannerView.adHeight)
                        .animation(.easeInOut(duration: 2.0))
                }

                BorderView()

                Text(ARCHLocalizedStrings.receipt)
                    .foregroundColor(Color.gray)

                BorderView() …
Run Code Online (Sandbox Code Playgroud)

swiftui combine

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

SwiftUI - 如何在 HStack 中左、中、右对齐元素?

我正在创建一个 iOS 扫雷游戏,并希望在顶部有一个包含三条信息的栏:

  • 高分(奖杯符号旁边)[左]
  • 当前时间(计时器符号旁边)[CENTER]
  • 剩余炸弹数量(炸弹符号旁边)[右]

然而,正如您在底部的图片中看到的那样,元素并不是均匀对齐的 - 我猜垫片自动具有相同的尺寸。因此,由于屏幕左侧的文本比右侧的文本宽,因此中间的文本会向右偏移。

如何对齐这些项目,使中心时间/图像与左侧/右侧的其他对象完全位于中间?

我的代码如下所示:

struct GameView: View {
    @EnvironmentObject var game: Game
    @State var labelHeight = CGFloat.zero
    
    var body: some View {
        VStack(alignment: .center, spacing: 10) {
            Text("MINESWEEPER")
                .font(.system(size: 25, weight: .bold, design: .monospaced))
                .kerning(3)
                .foregroundColor(.red)
            
            HStack(alignment: .center, spacing: 5) {
                Image(systemName: "rosette")
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .foregroundColor(.black)
                Text(game.highScoreString)
                    .font(.system(size: 15, weight: .bold, design: .monospaced))
                    .foregroundColor(.black)

                Spacer()
                
                Image(systemName: "timer")
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .foregroundColor(.black)
                Text(game.timerString)
                    .font(.system(size: 15, weight: .bold, design: .monospaced))
                    .foregroundColor(.black)
                
                Spacer()
                
                Image("top_bomb")
                    .resizable() …
Run Code Online (Sandbox Code Playgroud)

user-interface xcode ios swift swiftui

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

在 SwiftUI 中使用参数初始化 @StateObject

我想知道目前是否有(在询问时,第一个 Xcode 12.0 Beta)使用@StateObject来自初始化程序的参数来初始化 a 的方法。

更具体地说,这段代码可以正常工作:

struct MyView: View {
  @StateObject var myObject = MyObject(id: 1)
}
Run Code Online (Sandbox Code Playgroud)

但这不会:

struct MyView: View {
  @StateObject var myObject: MyObject

  init(id: Int) {
    self.myObject = MyObject(id: id)
  }
}
Run Code Online (Sandbox Code Playgroud)

从我理解的作用@StateObject是使视图成为对象的所有者。我使用的当前解决方法是传递已经初始化的 MyObject 实例,如下所示:

struct MyView: View {
  @ObservedObject var myObject: MyObject

  init(myObject: MyObject) {
    self.myObject = myObject
  }
}
Run Code Online (Sandbox Code Playgroud)

但是现在,据我所知,创建对象的视图拥有它,而这个视图没有。

谢谢。

swift swiftui xcode12

44
推荐指数
4
解决办法
9233
查看次数

标签 统计

swiftui ×10

swift ×9

ios ×6

combine ×2

reactive ×1

user-interface ×1

xcode ×1

xcode12 ×1