Как изменить свойство объекта (opacity) при нажатии на кнопку
Подскажите пожалуйста как изменить свойства opacity в текстовых полях (otvet.otvetYes и otvet.otvetNo) при нажатии на кнопки Yes, No Задача по нажатию на кнопку yes получить в кругу Yes. Пытаюсь это сделать через изменение свойства opacity, но не как не могу до него добраться. Спасибо Вам за ответ!
'''
import SwiftUI
struct ContentView: View {
@State var array: [UUID] = []
var body: some View {
VStack {
HStack {
HStack {
Button("Yes") { } // Выводит Yes в первом поле
Button("No") { } // Выводит No в первом поле
}
.padding(.horizontal, 55)
Spacer()
}
HStack(spacing: 30) {
ForEach(otvetData) {
item in GameView(otvet: item)
}
}
}
.frame(width: 600, height: 400, alignment: .center)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct GameView: View {
var otvet: Otvet
var body: some View {
ZStack {
Circle()
.fill(Color.yellow)
.frame(width: 100, height: 100)
.shadow(color: .black, radius: 2, x: 3, y: 3)
Text("yes")
.foregroundColor(Color(#colorLiteral(red: 0.8039215686, green: 0.5215686275, blue: 0.09803921569, alpha: 1)))
.font(.system(size: 40))
.offset(y: -5)
.opacity(otvet.otvetYes ? 1 : 0)
Text("no")
.foregroundColor(Color(#colorLiteral(red: 0.8039215686, green: 0.5215686275, blue: 0.09803921569, alpha: 1)))
.font(.system(size: 40))
.offset(y: -5)
.opacity(otvet.otvetNo ? 1 : 0)
}
}
}
struct Otvet: Identifiable {
var id = UUID()
var otvetYes: Bool
var otvetNo: Bool
}
let otvetData = [
Otvet(otvetYes: false, otvetNo: false),
Otvet(otvetYes: false, otvetNo: false),
Otvet(otvetYes: false, otvetNo: false),
Otvet(otvetYes: false, otvetNo: false)
]
'''
Ответы (1 шт):
Можно использовать здесь @ObservedObject для обновления данных в массиве, отдельный вопрос при этом - у вас всего 2 кнопки Yes/No, может быть несколько кругов с ответами, поэтому непонятно по какому принципу связывать кнопки и круги, в связи с этим я оставил для простоты один круг, также я переименовал русифицированные переменные otvet -> answer
import SwiftUI
class Answer: ObservableObject, Identifiable {
let id = UUID()
@Published var answerYes = false
@Published var answerNo = false
init(answerYes: Bool, answerNo: Bool) {
self.answerYes = answerYes
self.answerNo = answerNo
}
}
class Answers: ObservableObject {
@Published var items = [Answer]()
init(_ items: [Answer]) {
self.items = items
}
}
struct ContentView: View {
@ObservedObject var answers: Answers
var body: some View {
VStack {
HStack {
HStack {
Button("Yes") {
answers.items.first!.answerNo = false
answers.items.first!.answerYes = true
} // Выводит Yes в первом поле
Button("No") {
answers.items.first!.answerNo = true
answers.items.first!.answerYes = false
} // Выводит No в первом поле
}
}
HStack(spacing: 30) {
ForEach(answers.items) { item in
GameView(answer: item)
}
}
}
.frame(width: 600, height: 400, alignment: .center)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(answers: Answers([
Answer(answerYes: false, answerNo: false)
]))
}
}
struct GameView: View {
@ObservedObject var answer: Answer
var body: some View {
ZStack {
Circle()
.fill(Color.yellow)
.frame(width: 100, height: 100)
.shadow(color: .black, radius: 2, x: 3, y: 3)
Text("yes")
.foregroundColor(Color(#colorLiteral(red: 0.8039215686, green: 0.5215686275, blue: 0.09803921569, alpha: 1)))
.font(.system(size: 40))
.offset(y: -5)
.opacity(answer.answerYes ? 1 : 0)
Text("no")
.foregroundColor(Color(#colorLiteral(red: 0.8039215686, green: 0.5215686275, blue: 0.09803921569, alpha: 1)))
.font(.system(size: 40))
.offset(y: -5)
.opacity(answer.answerNo ? 1 : 0)
}
}
}
Данный пример можно упростить - оставить 1 флаг для ответа yes/no и вместо opacity двух лейблов просто менять текст в одном, а чтобы управлять opacity, можно сделать свойство answerYes опциональным
class Answer: ObservableObject, Identifiable {
let id = UUID()
@Published var answerYes: Bool?
init(answerYes: Bool?) {
self.answerYes = answerYes
}
}
class Answers: ObservableObject {
@Published var items = [Answer]()
init(_ items: [Answer]) {
self.items = items
}
}
struct ContentView: View {
@ObservedObject var answers: Answers
var body: some View {
VStack {
HStack {
HStack {
Button("Yes") {
answers.items.first!.answerYes = true // TODO: переделать логику обращения к элементам массива
} // Выводит Yes в первом поле
Button("No") {
answers.items.first!.answerYes = false // TODO: переделать логику обращения к элементам массива
} // Выводит No в первом поле
}
}
HStack(spacing: 30) {
ForEach(answers.items) { item in
GameView(answer: item)
}
}
}
.frame(width: 600, height: 400, alignment: .center)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(answers: Answers([
Answer(answerYes: nil)
]))
}
}
struct GameView: View {
@ObservedObject var answer: Answer
var body: some View {
ZStack {
Circle()
.fill(Color.yellow)
.frame(width: 100, height: 100)
.shadow(color: .black, radius: 2, x: 3, y: 3)
Text(answer.answerYes == nil ? "" : answer.answerYes! ? "yes" : "no")
.foregroundColor(Color(#colorLiteral(red: 0.8039215686, green: 0.5215686275, blue: 0.09803921569, alpha: 1)))
.font(.system(size: 40))
.offset(y: -5)
.opacity(answer.answerYes == nil ? 0 : 1)
}
}
}
Дополнение - добавление кнопок
Можно перенести кнопки в GameView
struct ContentView: View {
@ObservedObject var answers: Answers
var body: some View {
HStack {
ForEach(answers.items) { item in
GameView(answer: item)
}
}
.frame(width: 600, height: 400, alignment: .center)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(answers: Answers([
Answer(answerYes: nil),
Answer(answerYes: nil),
Answer(answerYes: nil),
Answer(answerYes: nil)
]))
}
}
struct GameView: View {
@ObservedObject var answer: Answer
var body: some View {
VStack {
// buttons
HStack {
HStack {
Button("Yes") {
answer.answerYes = true
} // Выводит Yes в первом поле
Button("No") {
answer.answerYes = false
} // Выводит No в первом поле
}
}
// circle
ZStack {
Circle()
.fill(Color.yellow)
.frame(width: 100, height: 100)
.shadow(color: .black, radius: 2, x: 3, y: 3)
Text(answer.answerYes == nil ? "" : answer.answerYes! ? "yes" : "no")
.foregroundColor(Color(#colorLiteral(red: 0.8039215686, green: 0.5215686275, blue: 0.09803921569, alpha: 1)))
.font(.system(size: 40))
.offset(y: -5)
.opacity(answer.answerYes == nil ? 0 : 1)
}
}
}
}
Дополнение 2 - условный вывод текста
opacity можно вообще не использовать, просто сделав вывод текста опциональным через условие if
// circle
ZStack {
Circle()
.fill(Color.yellow)
.frame(width: 100, height: 100)
.shadow(color: .black, radius: 2, x: 3, y: 3)
if let answerYes = answer.answerYes {
Text(answerYes ? "yes" : "no")
.foregroundColor(Color(#colorLiteral(red: 0.8039215686, green: 0.5215686275, blue: 0.09803921569, alpha: 1)))
.font(.system(size: 40))
.offset(y: -5)
}
}