如果我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)
但两者之间的实际区别是什么?有没有一种情况比另一种更好,或者它们是两种完全不同的东西?
我试图使用 SwiftUI@Environment属性包装器,但我无法使其按预期工作。请帮助我理解我做错了什么。
例如,我有一个每秒生成一个整数的对象:
class IntGenerator: ObservableObject {
@Published var newValue = 0 {
didSet {
print(newValue)
}
}
private var toCanc: AnyCancellable?
init() {
toCanc = Timer.TimerPublisher(interval: 1, runLoop: .main, mode: .default)
.autoconnect()
.map { _ in Int.random(in: 0..<1000) }
.assign(to: \.newValue, on: self)
}
}
Run Code Online (Sandbox Code Playgroud)
这个对象按预期工作,因为我可以看到控制台日志上生成的所有整数。现在,假设我们希望这个对象是一个可以从整个应用程序和任何人访问的环境对象。让我们创建相关的环境键:
struct IntGeneratorKey: EnvironmentKey {
static let defaultValue = IntGenerator()
}
extension EnvironmentValues {
var intGenerator: IntGenerator {
get {
return self[IntGeneratorKey.self]
}
set {
self[IntGeneratorKey.self] = newValue
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在我可以像这样访问这个对象(例如从视图中): …
当您定义自己的属性包装器时,您必须指定一个名为 'wrappedValue'的非静态属性。例如:
@propertyWrapper
struct MyPropertyWrapper<Value> {
var value: Value
}
Run Code Online (Sandbox Code Playgroud)
使用上面的代码,编译器抱怨:
属性包装器类型“MyPropertyWrapper”不包含名为“wrappedValue”的非静态属性
因此,您只需执行以下操作即可修复错误:
@propertyWrapper
struct MyPropertyWrapper<Value> {
var value: Value
var wrappedValue: Value {
get {
value
}
set {
value = newValue
}
}
}
Run Code Online (Sandbox Code Playgroud)
只是举一些例子,这适用于@State:
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
@propertyWrapper public struct State<Value> : DynamicProperty {
/// The current state value.
public var wrappedValue: Value { get nonmutating set }
}
Run Code Online (Sandbox Code Playgroud)
相同的@Binding:
@available(iOS 13.0, OSX …Run Code Online (Sandbox Code Playgroud) 我正在研究这门swift语言,我对a中的变量初始化有疑问UIViewController.在我的DiagramViewController我有一些变数:
class DiagramViewController: UIViewController {
var type: Constants.DiagramType
var filename: String
var numberOfBars: Int
var numberOfSection: Int
var diagramName: String
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Run Code Online (Sandbox Code Playgroud)
Swift需要这些var的init值,我可以通过多种方式实现,但是我应该如何在这些方式之间做出选择呢?
我可以初始化变量"inline":
class DiagramViewController: UIViewController {
var type: Constants.DiagramType = Constants.DiagramType.HISTOGRAM
var filename: String = "dd.txt"
var numberOfBars: Int = 10
var numberOfSection: …Run Code Online (Sandbox Code Playgroud) 在SwiftUI我们使用NavigationView和NavigationLink意见进行导航(我们习惯称之为segue中UIKit)。UIKit中的标准segue是showsegue。在SwiftUI中,我们可以简单地执行以下操作:
struct ContentView: View {
var body: some View {
NavigationView {
VStack {
NavigationLink(destination: Text("Destination")) {
Text("Navigate!")
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
具有完全相同的效果(即使单词segue消失了)。
有时(实际上是经常),我们需要自定义segue动画。
Animates通过单击动画来在属性检查器中找到该属性(true / false)。这样,目标视图控制器将立即代替源视图控制器出现。UIViewControllerAnimatedTransitioning协议的对象来完成的。所有的魔术都发生在animateTransition使我们能够访问源视图控制器和目标视图控制器的方法中。例如,一个简单的淡入淡出segue动画可能类似于:
-(void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext{
UIView* containerView = [transitionContext containerView];
UIViewController* fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController* toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
toVC.view.alpha = 0;
[containerView addSubview:toVC.view];
[UIView animateWithDuration:1 animations:^{
toVC.view.alpha = 1;
fromVC.view.alpha = 0;
} completion:^(BOOL …Run Code Online (Sandbox Code Playgroud) 我不明白为什么DragGesture在 VStack/HStack/ZStack 上不起作用。考虑以下简单示例:
struct ContentView: View {
@State private var offset = CGSize.zero
var body: some View {
VStack {
Text("Hello World!")
}
.frame(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
.edgesIgnoringSafeArea(.all)
.offset(y: offset.height)
.gesture(DragGesture()
.onChanged { val in
self.offset = val.translation
}
.onEnded { val in
self.offset = .zero
}
)
}
}
Run Code Online (Sandbox Code Playgroud)
我希望整个视图根据offsetvar上下移动(由拖动手势改变)。但是,即使我写.gesture上的修饰VStack,甚至如果VStack是全屏幕(得益于.frame修改)拖动动作将不会在工作VStack。该手势仅在我拖动“Hello world”文本时有效,但如果我拖动到外部Text(但仍在全屏内部VStack)则无响应。有任何想法吗?谢谢。
在 SwiftUI 中是否可以有一个可选的@ViewBuilder闭包?例如,假设我想开发一个自定义视图,它采用两个视图构建器闭包,如下所示:
import SwiftUI
struct TopAndBottomView<Content>: View where Content: View {
let topContent: () -> Content
let bottomContent: () -> Content
init(@ViewBuilder topContent: @escaping () -> Content, @ViewBuilder bottomContent: @escaping () -> Content) {
self.topContent = topContent
self.bottomContent = bottomContent
}
var body: some View {
VStack {
topContent()
Spacer()
bottomContent()
}
}
}
struct TopAndBottomView_Previews: PreviewProvider {
static var previews: some View {
TopAndBottomView(topContent: {
Text("TOP")
}, bottomContent: {
Text("BOTTOM")
})
}
}
Run Code Online (Sandbox Code Playgroud)
但我希望底部视图是可选的。我试过:
struct TopAndBottomView<Content>: …Run Code Online (Sandbox Code Playgroud) 在 UIKit 中,我们有一个UIScrollView方法可以让滚动指示器短暂闪烁,以通知用户屏幕上有滚动内容(这并不总是很明显)。苹果说:
func flashScrollIndicators()
Run Code Online (Sandbox Code Playgroud)
每当您将滚动视图置于前面时,您都应该调用此方法。
我的问题是:如何在 SwiftUI 上获得相同的效果?看一下这个非常愚蠢的例子,只是为了说明问题:
如果您看一下此屏幕,您将无法知道是否可以滚动某些内容:
但你实际上可以:
如何让用户意识到 SwiftUI 上的滚动内容?
我需要你的帮助:我正在与另一个人一起开展一个网络项目.我正在使用NetBeans开发代码,而他正在使用Dreamweaver.我们想忽略所有Dreamweaver _notes目录(这些目录包含Dreamweaver自己生成的文件).我们不知道这些目录的确切路径.我们可以/a/b/c/_notes/f在/_notes/a/b/c或在其他几十个地方找到它们.我们试图添加
/_notes/
/nbproject
configs/
Run Code Online (Sandbox Code Playgroud)
和
/_notes
/nbproject
configs/
Run Code Online (Sandbox Code Playgroud)
并且
*_notes*
/nbproject
configs/
Run Code Online (Sandbox Code Playgroud)
到.gitignore文件,但仍然跟踪_notes目录.有什么建议?先感谢您!
我不能理解如何在SwiftUI @Binding中结合使用ForEach。假设我要Toggle根据布尔数组创建s 的列表。
struct ContentView: View {
@State private var boolArr = [false, false, true, true, false]
var body: some View {
List {
ForEach(boolArr, id: \.self) { boolVal in
Toggle(isOn: $boolVal) {
Text("IsOn")
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我不知道如何将绑定传递给数组中的布尔对象Toggle。上面的代码给出此错误:
使用未解决的标识符“ $ boolVal”
好的,这对我来说很好(当然)。我试过了:
struct ContentView: View {
@State private var boolArr = [false, false, true, true, false]
var body: some View {
List {
ForEach($boolArr, id: \.self) { boolVal in
Toggle(isOn: boolVal) …Run Code Online (Sandbox Code Playgroud) ios ×9
swift ×9
swiftui ×8
animation ×1
binding ×1
data-binding ×1
dreamweaver ×1
git ×1
gitignore ×1
uikit ×1
uiscrollview ×1
variables ×1