Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如果在SwiftUI中使用onChange或PreferenceKey修饰符,则会出现不必要的渲染问题_Swift_Swiftui - Fatal编程技术网

如果在SwiftUI中使用onChange或PreferenceKey修饰符,则会出现不必要的渲染问题

如果在SwiftUI中使用onChange或PreferenceKey修饰符,则会出现不必要的渲染问题,swift,swiftui,Swift,Swiftui,在下面的代码中,我在一个名为TextView的自定义视图中使用了绑定,它不会在它的主体中使用这个绑定,它只是坐在那里 当我们在项目中使用onChange或PreferenceKey时,事情会变得很奇怪,这会改变主体中未使用的绑定的视图行为。因此,如果我们在项目中不使用onChange或PreferenceKey,并且我们在项目中更新了未使用的绑定,而该绑定不会使视图呈现,甚至我们不需要定义并遵循公平函数来帮助SwiftUI理解它是同一个视图,那么就会发生这种情况。即使没有定义公平功能或遵守公平协

在下面的代码中,我在一个名为TextView的自定义视图中使用了绑定,它不会在它的主体中使用这个绑定,它只是坐在那里

当我们在项目中使用onChange或PreferenceKey时,事情会变得很奇怪,这会改变主体中未使用的绑定的视图行为。因此,如果我们在项目中不使用onChange或PreferenceKey,并且我们在项目中更新了未使用的绑定,而该绑定不会使视图呈现,甚至我们不需要定义并遵循公平函数来帮助SwiftUI理解它是同一个视图,那么就会发生这种情况。即使没有定义公平功能或遵守公平协议,它也会起作用。但是,当我们在未使用的绑定上使用onChange或PreferenceKey时,即使我们为视图使用并定义了公平和公平的函数,它也会以任何方式呈现它!即使没有必要,我也不知道如何解决这个问题

    struct ContentView: View {

    @State private var string: String = "Hello" {

        didSet {

            print(string)

        }

    }


    var body: some View {

        EquatableView(content: TextView(string: $string))

        Button("update") { string += " updated!" }
          //.onChange(of: string) { newValue in  }  // <<: Here!!!

    }

}

struct TextView: View, Equatable {

    @Binding var string: String

    let value: String = "123"

    var body: some View {

        print("rendering TextView!", "- - - - - - ")

        return Text(value)

    }

    static func == (lhs: TextView, rhs: TextView) -> Bool {

        print("Equatable function used!")

        return lhs.value == rhs.value

    }

}
struct ContentView:View{
@国家私有变量字符串:string=“Hello”{
迪塞特{
打印(字符串)
}
}
var body:一些观点{
equalTableView(内容:TextView(字符串:$string))
按钮(“更新”){string+=“updated!”}

//.onChange(of:string){newValue in}/当您添加
时。onChange(of:string){…}
您在
ContentView
body
中引用
string
,如果值更改,将执行ContentView的body,从而
TextView的
body

在没有
.onChange
的设置中,您没有在ContentView主体中引用
字符串的值,对该值的更改不会导致ContentView被重新绘制。无论是否使用EquatableView,单击按钮时都不应调用
文本视图的
主体

我认为,在您的伪代码中,您不需要EquatableView——因为没有可以优化的东西,而且SwiftUI的默认行为工作得很好

到目前为止,它的工作情况与预期相符

现在,您的问题归结为:如果超级视图发生更改,如何避免重画子视图?(阅读:如果将执行超级视图的
body
,如何不执行子视图的
body

嗯,我认为,SwiftUI可以进行优化,但我不认为当超级视图发生变化并被重新绘制时,它通常可以忽略重新绘制子视图

现在,当我考虑它时,您可以使用“ContentView”作为equalableview的参数