I have the following SwiftUI view which is essentially a textfield containing a button:
var body: some View {
ZStack(alignment: .leading) {
RoundedRectangle(cornerRadius: Constants.cornerRadius, style: .continuous)
.stroke(isFocused ? Color.blue : hasWarning ? .blue : .gray, lineWidth: Constants.lineWidth)
HStack {
Text(title)
.font(.bodyFont)
.foregroundColor(isFocused ? Color.blue : hasWarning ? .red : .gray)
.padding(.horizontal, text.isEmpty ? Constants.Padding.horizontalIsEmpty : Constants.Padding.horizontalIsNotEmpty)
.background(text.isEmpty ? Color.clear : background)
.padding(.leading, Constants.Padding.leading)
.offset(y: text.isEmpty ? Constants.Offset.isEmpty : -(frameHeight / Constants.Offset.isNotEmptyRatio))
.scaleEffect(text.isEmpty ? Constants.ScaleEffect.isEmpty : Constants.ScaleEffect.isNotEmpty, anchor: .leading)
if let button = button {
Spacer()
Button(action: {
button.action()
}, label: {
Text(button.labelText)
})
.padding(.trailing, Constants.Button.trailingPadding)
}
}
TextField("", text: $text, onEditingChanged: { inFocus in
self.isFocused = inFocus
})
.font(.bodyFont)
.padding(.horizontal, Constants.Padding.horizontal)
}
.frame(height: frameHeight)
.background(background)
.animation(.easeInOut(duration: Constants.Animation.easeInOut))
.padding(.top, Constants.Padding.top)
}
The result is a field like this:
However, only the very right hand side of the button is tappable.
I have tried adding a contentShape, like this:
if let button = button {
Spacer()
Button(action: {
button.action()
}, label: {
Text(button.labelText)
})
.contentShape(Rectange())
.padding(.trailing, Constants.Button.trailingPadding)
}
However this has made no difference. Wondering where I'm going wrong here.
