swift - 如何在每次内容 View 加载时生成一个新的随机数?

标签 swift xcode swiftui

此处的目的是在每次加载 MyView 时生成一个新的随机数,同时保持随机生成的数字不受任何 MyView 刷新的影响。但是,以下方法均无效。我将解释每种方法及其结果。关于如何正确完成我的要求有什么想法吗?

方法#1:我假设每次加载 MyView 时都会生成一个新数字。但是,在整个应用程序生命周期中都会生成一次随机数。我放置了一个按钮来强制刷新 View ,因此当我按下该按钮时,不应生成新的随机数,这就是发生的情况。 这种方法有什么问题吗?

import SwiftUI

struct ContentView: View {

    var body: some View {
    
        NavigationView {
        
            NavigationLink(destination: MyView()) {
                Text("Link to MyView")
            }
        }
    }
}

struct MyView: View {

    @State var randomInt = Int.random(in: 1...100)
    @State var myMessage: String = ""

    var body: some View {

        Text(String(randomInt))

        Button("Press Me") { 
            myMessage = String(randomInt)
        }

        Text(myMessage)
    }

}

方法#2:我尝试通过 Body 内部的 let 更新 randomInt 变量,但这会在每次按下按钮时生成一个新的随机数(这会强制刷新 View )。再说一次,这不是预期的结果。 这种方法有什么问题吗?

import SwiftUI

struct ContentView: View {

    var body: some View {
    
        NavigationView {
        
            NavigationLink(destination: MyView()) {
                Text("Link to MyView")
            }
        }
    }
}

struct MyView: View {

    @State var randomInt = 0
    @State var myMessage: String = ""

    var body: some View {
        
        let randomInt = Int.random(in: 1...100)
        
        Text(String(randomInt))

        Button("Press Me") { 
            myMessage = String(randomInt)
        }

        Text(myMessage)

    }

}

方法#3:这里的想法是每次按下“Link to MyView”时传递一个新的随机生成的整数。我假设每次加载内容 View 时都会运行并传递 Int.Random。但是,仅在整个应用程序第一次运行时才会生成随机数。 这种方法有什么问题吗?

import SwiftUI

struct ContentView: View {

    var body: some View {
    
        NavigationView {
        
            NavigationLink(destination: MyView(randomInt: Int.random(in: 1...100))) {
                Text("Link to MyView")
            }
        }
    }
}

struct MyView: View {

    @State var randomInt = 0
    @State var myMessage: String = ""

    var body: some View {
        Text(myMessage)

        Button("Press Me") { 
            myMessage = String(randomInt)
        }
    }

}

最佳答案

方法#1:

MyView创建一次,当 ContentView渲染。

内部MyView , randomInt在第一次创建 View 时设置,然后从未修改过。当您按下按钮时,myMessage已设置,但是 randomInt从未改变。如果你想要randomInt要更改,您需要这样说:

randomInt = Int.random(in: 1...100)

在按钮操作内:

方法#2:

您正在创建一个 randomInt通过声明 let randomInt = 在本地范围内变量在 View 主体内。

相反,如果我正确地阅读了您最初的问题,我认为您会想要使用 onAppear 的东西:

struct MyView: View {

    @State var randomInt = 0
    @State var myMessage: String = ""

    var body: some View {
        VStack {
            Text(String(randomInt))

            Button("Press Me") {
                myMessage = String(randomInt)
            }

            Text(myMessage)
        }.onAppear {
            randomInt = Int.random(in: 1...100)
        }
    }
}

您将看到,每次您返回导航层次结构然后重新访问 MyView 时,都会有一个新值(因为它再次出现)。触发重新渲染的按钮不会重新触发onAppear

方法#3:

MyView在父 View ( ContentView ) 的第一次渲染时创建。除非有东西触发 ContentView 的刷新,您不会在这里生成新的随机数。


总之,我有点不清楚最初的要求是什么( View “加载”意味着什么?这只是意味着它何时显示在屏幕上?),但希望这描述了每个场景并可能引入 onAppear 的想法,这似乎可能就是您正在寻找的内容。


附录:如果您希望仅在 ContentView 时生成随机数加载(如标题所示),我会在 ContentView 中创建它而不是你的MyView并将其作为参数传递。


struct ContentView: View {
    @State var randomInt = Int.random(in: 1...100)
    
    var body: some View {
        
        NavigationView {
            
            NavigationLink(destination: MyView(randomInt: $randomInt)) {
                Text("Link to MyView")
            }
        }
    }
}

struct MyView: View {
    
    @Binding var randomInt : Int
    @State var myMessage: String = ""
    
    var body: some View {
        
        Text(String(randomInt))
        
        Button("Press me to refresh only myMessage") {
            myMessage = String(randomInt)
        }
        
        Button("Press me to change the randomInt as well") {
            randomInt = Int.random(in: 1...100)
            myMessage = String(randomInt)
        }
        
        Text(myMessage)
    }
    
}

关于swift - 如何在每次内容 View 加载时生成一个新的随机数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66510179/

相关文章:

ios - 如何在 firebase 的节点中添加子节点

ios - 使用 Bool 通过 SwiftUI 动态过滤 @FetchRequest - 显示 true、false 或两者

ios - UICollectionView 更改 Drop Placeholder 索引路径

ios - 应用程序从后台返回后,UITabBarController selectedIndex 未更新

ios - iOS 应用的动态内容

swiftui - 多级导航 SwiftUI

SwiftUI GKLeaderboard loadEntries

multithreading - 如何在执行后台任务时呈现 View Controller ?

ios - 这些闭包中的保留周期有什么区别?标准闭包与对象初始化闭包

ios - 意外发现标签和表格 View 为零