1. RoundedRectangle CheckBox
Với loại checkbox đầu tiên chúng tạo tạo một struct view và thêm RoundedRectangle
. Sử dụng hàm stroke
và thêm cho nó StrikeStyle
với kích thước dòng kẻ mà bạn mong muốn.
struct CheckBoxView: View { var body: some View { RoundedRectangle(cornerRadius: 10) .trim(from: 0, to: 1) .stroke(style: StrokeStyle(lineWidth: 2)) .frame(width: 70, height: 70) .foregroundColor(.green) }
}
Tiếp theo đưa RoundedRectangle
vào ZStack
và thêm một RoundedRectangle
khác vào. Chắc chắn rằng RoundedRectangle
thứ hai nhỏ hơn cái trước đó.
struct CheckBoxView: View { var body: some View { ZStack { RoundedRectangle(cornerRadius: 10) .trim(from: 0, to: 1) .stroke(style: StrokeStyle(lineWidth: 2)) .frame(width: 70, height: 70) .foregroundColor(.green) RoundedRectangle(cornerRadius: 10) .trim(from: 0, to: 1) .fill(Color.green) .frame(width: 60, height: 60) } }
}
Khai báo một biến Bool binding gọi là checked
ở đầu struct. Thêm dấu tick bên dưới RoundedRectangle
thứ hai như sau:
struct CheckBoxView: View { @Binding var checked: Bool var body: some View { ZStack { RoundedRectangle(cornerRadius: 10) .trim(from: 0, to: 1) .stroke(style: StrokeStyle(lineWidth: 2)) .frame(width: 70, height: 70) .foregroundColor(checked ? Color.green : Color.gray.opacity(0.2)) RoundedRectangle(cornerRadius: 10) .trim(from: 0, to: 1) .fill(checked ? Color.green : Color.gray.opacity(0.2)) .frame(width: 60, height: 60) if checked { Image(systemName: "checkmark") .foregroundColor(Color.white) } } }
}
Khai báo một biến khác để kiểm soát hàm trim
của RoundedRectangle
đầu tiên. Nó sẽ dùng để tạo ra animation.
@Binding var trimVal: CGFloat var animationData: CGFloat { get { trimVal } set { trimVal = newValue } }
Sau đó hãy thay đổi trim
bằng giá trị biến mới.
RoundedRectangle(cornerRadius: 10) .trim(from: 0, to: trimVal) .stroke(style: StrokeStyle(lineWidth: 2)) .frame(width: 70, height: 70) .foregroundColor(checked ? Color.green : Color.gray.opacity(0.2))
Bạn đã xong bước khởi tạo giờ quay lại ContentView
để thêm CheckBoxView
vào đó.
struct ContentView: View { @State var trimVal: CGFloat = 0 @State var checked = false var body: some View { Button(action: { }) { CheckBoxView(checked: $checked, trimVal: $trimVal) } }
}
Kết quả thu được như sau:
2. Circular CheckBox
Bạn có thể trở lại file CheckBoxView
và thay đổi shape thành circle như sau:
var body: some View { ZStack { Circle() .trim(from: 0, to: trimVal) .stroke(style: StrokeStyle(lineWidth: 2)) .frame(width: 70, height: 70) .foregroundColor(self.checked ? Color.green : Color.gray) .overlay( Circle() .fill(self.checked ? Color.green : Color.gray.opacity(0.2)) .frame(width: 60, height: 60) ) if checked { Image(systemName: "checkmark") .foregroundColor(Color.white) } } }
3. Capsule CheckBox
Tiếp theo hãy tạo một loại thú vị hơn nhé. Thêm hai biến width
và removeText
.
Thuộc tính width
được sử dụng cho capsule frame, để đảm bảo phần thứ 2 nhỏ hơn phần thứ nhất hãy lấy width - 10, cuối cùng hãy thêm nó vào một lệnh if như sau:
struct CheckBoxView: View { @Binding var checked: Bool @Binding var trimVal: CGFloat @Binding var width: CGFloat @Binding var removeText: Bool var animationData: CGFloat { get { trimVal } set { trimVal = newValue } } var body: some View { ZStack { Capsule() .trim(from: 0, to: trimVal) .stroke(style: StrokeStyle(lineWidth: 2)) .frame(width: width, height: 70) .foregroundColor(self.checked ? Color.green : Color.gray) .overlay( Capsule() .fill(self.checked ? Color.green : Color.gray.opacity(0.2)) .frame(width: width - 10, height: 60) ) if checked { Image(systemName: "checkmark") .foregroundColor(Color.white) .opacity(Double(trimVal)) } if !removeText { Text("Check Mark") } } }
}
Trong ContentView
sẽ điều chỉnh lại như sau:
struct ContentView: View { @State var trimVal: CGFloat = 0 @State var checked = false @State var width: CGFloat = 200 @State var removeText: Bool = false var body: some View { CheckBoxView(checked: $checked, trimVal: $trimVal, width: $width, removeText: $removeText) .onTapGesture { if !self.checked { self.removeText.toggle() withAnimation { self.width = 70 } withAnimation(Animation.easeIn(duration: 0.7)) { self.trimVal = 1 self.checked.toggle() } } else { withAnimation { self.trimVal = 0 self.width = 200 self.checked.toggle() self.removeText.toggle() } } } }
}
Ở trên mình chia sẻ một số loại cơ bản. Bạn có thể từ đó tạo ra nhiều loại animation đẹp mắt hơn nữa nhé.
Nguồn:
https://medium.com/better-programming/how-to-create-and-animate-checkboxes-in-swiftui-e428fe7cc9c1