Argh! Bạn đã rất gần. Đây là cách bạn làm điều đó. Bạn đã bỏ lỡ ký hiệu đô la (beta 3) hoặc dấu gạch dưới (beta 4) và tự đứng trước thuộc tính số tiền của mình hoặc .value sau thông số số tiền. Tất cả các tùy chọn này hoạt động:
Bạn sẽ thấy rằng tôi đã xóa @State
trong includeDecimal, hãy kiểm tra phần giải thích ở cuối.
Đây là cách sử dụng thuộc tính (đặt bản thân trước nó):
struct AmountView : View {
@Binding var amount: Double
private var includeDecimal = false
init(amount: Binding<Double>) {
self._amount = amount
self.includeDecimal = round(self.amount)-self.amount > 0
}
}
hoặc sử dụng .value sau (nhưng không có tự, vì bạn đang sử dụng tham số được truyền, không phải thuộc tính của struct):
struct AmountView : View {
@Binding var amount: Double
private var includeDecimal = false
init(amount: Binding<Double>) {
self._amount = amount
self.includeDecimal = round(amount.value)-amount.value > 0
}
}
Điều này giống nhau, nhưng chúng tôi sử dụng các tên khác nhau cho tham số (withAmount) và thuộc tính (số tiền), vì vậy bạn có thể thấy rõ khi nào bạn đang sử dụng mỗi tên.
struct AmountView : View {
@Binding var amount: Double
private var includeDecimal = false
init(withAmount: Binding<Double>) {
self._amount = withAmount
self.includeDecimal = round(self.amount)-self.amount > 0
}
}
struct AmountView : View {
@Binding var amount: Double
private var includeDecimal = false
init(withAmount: Binding<Double>) {
self._amount = withAmount
self.includeDecimal = round(withAmount.value)-withAmount.value > 0
}
}
Lưu ý rằng .value là không cần thiết với thuộc tính, nhờ vào trình bao bọc thuộc tính (@Binding), nó tạo ra các trình truy cập làm cho .value không cần thiết. Tuy nhiên, với tham số, không có điều đó và bạn phải làm điều đó một cách rõ ràng. Nếu bạn muốn tìm hiểu thêm về trình bao bọc thuộc tính, hãy xem phiên WWDC 415 - Thiết kế API Swift hiện đại và chuyển đến 23:12.
Như bạn đã phát hiện, việc sửa đổi biến @State từ trình khởi tạo sẽ gây ra lỗi sau: Chủ đề 1: Lỗi nghiêm trọng: Truy cập Trạng thái bên ngoài View.body . Để tránh điều đó, bạn nên xóa @State. Điều này có ý nghĩa vì includeDecimal không phải là nguồn chân lý. Giá trị của nó bắt nguồn từ số lượng. Tuy nhiên, bằng cách xóa @State includeDecimal
sẽ không cập nhật nếu số lượng thay đổi. Để đạt được điều đó, tùy chọn tốt nhất là xác định includeDecimal của bạn như một thuộc tính được tính toán, để giá trị của nó được lấy từ nguồn chân lý (số tiền). Bằng cách này, bất cứ khi nào số tiền thay đổi, includeDecimal của bạn cũng vậy. Nếu chế độ xem của bạn phụ thuộc vào includeDecimal, chế độ xem sẽ cập nhật khi nó thay đổi:
struct AmountView : View {
@Binding var amount: Double
private var includeDecimal: Bool {
return round(amount)-amount > 0
}
init(withAmount: Binding<Double>) {
self.$amount = withAmount
}
var body: some View { ... }
}
Như được chỉ ra bởi rob mayoff , bạn cũng có thể sử dụng $$varName
(beta 3) hoặc _varName
(beta4) để khởi tạo biến Trạng thái:
$$includeDecimal = State(initialValue: (round(amount.value) - amount.value) != 0)
_includeDecimal = State(initialValue: (round(amount.value) - amount.value) != 0)
self.includeDecimal = round(self.amount)-self.amount > 0
củaThread 1: Fatal error: Accessing State<Bool> outside View.body