- vừa được xem lúc

Tạo custom style cho Button trong SwiftUI

0 0 25

Người đăng: hungbv

Theo Viblo Asia

I. Giới thiệu

Trong một bài viết trước, tôi đã giới thiệu cách tạo custom Modifier cho view trong SwiftUI. Lợi ích của việc tạo custom Modifier thì đã rõ, giúp chúng ta có thể reuse code, và ở những chỗ sử dụng custom Modifier, code gọn gàng đi rất nhiều. Ngoài custom Modifier, chúng ta cũng có thể sử dụng một cách gần tương tự khác: tạo custom style. Tuy nhiên, custom style không áp dụng được với tất cả View, mà chỉ được áp dụng cho một số type View được support nhất định như: Button, List, Picker, Toggle, TextField,… và mỗi custom style của View nào thì chỉ sử dụng cho View đó. Tất nhiên có mất thì cũng có được, custom Style cũng có những điểm hơn Custom Modifier, trong bài viết này chúng ta sẽ tìm hiểu cách tạo custom Style cho Button

II. Nội dung

1. Tạo project

Đầu tiên, chúng ta tạo project với tên SwiftUITutorial, với interface là SwiftUI -> create project

Tiếp theo, chúng ta tạo các button với nội dung như sau:

struct ContentView: View { var body: some View { VStack(spacing: 20) { Button(action: { print("Car tapped") }) { HStack { Image(systemName: "car.fill") .font(.title) Text("Car") .fontWeight(.semibold) .font(.title) } } Button(action: { print("Bus tapped") }) { HStack { Image(systemName: "bus.fill") .font(.title) Text("Bus") .fontWeight(.semibold) .font(.title) } } Button(action: { print("Bicycle tapped") }) { HStack { Image(systemName: "bicycle") .font(.title) Text("Bicycle") .fontWeight(.semibold) .font(.title) } } } }
}

Ta được màn hình như hình dưới

2. Thêm design với các Modifier

Giả sử với mỗi Button, chúng ta cần thêm các modifier sau:

  • foregroundColor: white
  • background: gradient color với 2 màu red - yellow
  • cornerRadius: 5
  • kích thước: chiều rộng ra sát viền, cách viền 20 point

Nếu không tạo custom Modifier, thông thường chúng ta sẽ phải copy/paste các đoạn code design vào ContentView như sau:

struct ContentView: View { var body: some View { VStack(spacing: 20) { Button(action: { print("Car tapped") }) { HStack { Image(systemName: "car.fill") .font(.title) Text("Car") .fontWeight(.semibold) .font(.title) } // additional modifiers .frame(minWidth: 0, maxWidth: .infinity) .foregroundColor(.white) .background(LinearGradient(gradient: Gradient(colors: [Color.red, Color.yellow]), startPoint: .leading, endPoint: .trailing)) .cornerRadius(5) .padding(.horizontal, 20) } Button(action: { print("Bus tapped") }) { HStack { Image(systemName: "bus.fill") .font(.title) Text("Bus") .fontWeight(.semibold) .font(.title) } // additional modifiers .frame(minWidth: 0, maxWidth: .infinity) .foregroundColor(.white) .background(LinearGradient(gradient: Gradient(colors: [Color.red, Color.yellow]), startPoint: .leading, endPoint: .trailing)) .cornerRadius(5) .padding(.horizontal, 20) } Button(action: { print("Bicycle tapped") }) { HStack { Image(systemName: "bicycle") .font(.title) Text("Bicycle") .fontWeight(.semibold) .font(.title) } // additional modifiers .frame(minWidth: 0, maxWidth: .infinity) .foregroundColor(.white) .background(LinearGradient(gradient: Gradient(colors: [Color.red, Color.yellow]), startPoint: .leading, endPoint: .trailing)) .cornerRadius(5) .padding(.horizontal, 20) } } }
}

Kết quả được như hình sau

Bên trên,ta thêm cùng 1 đoạn code cho cả 3 button. Đoạn code đã trở nên khá là dài, và mỗi khi có thay đổi design thì phải lần lượt sửa code ở 3 chỗ. Chúng ta sẽ giải quyết vấn đề này ngay sau đây

3. Thêm Custom Style cho button

Đầu tiên, chúng ta thêm 1 file mới với tên MyCustomButtonStyle.swift: File -> New -> File -> Swift File -> Create file

Tiếp theo, để implement cho Custom Style chúng ta thêm code như sau:

import SwiftUI struct MyCustomButtonStyle: ButtonStyle { // 1 // 2 func makeBody(configuration: Self.Configuration) -> some View { // 3 configuration.label // 4 .frame(minWidth: 0, maxWidth: .infinity) .foregroundColor(.white) .background(LinearGradient(gradient: Gradient(colors: [Color.red, Color.yellow]), startPoint: .leading, endPoint: .trailing)) .cornerRadius(5) .padding(.horizontal, 20) }
}

Bên trên, chúng ta lần lượt làm những công việc sau:

    1. Tạo struct MyCustomButtonStyle, conform từ protocol ButtonStyle. Protocol này được Apple cung cấp sẵn, để chúng ta tự tạo style theo ý của mình
    1. Implement function makeBody(configuration:), đây là hàm của protocol ButtonStyle bắt buộc phải thêm. Hàm này trả về View là label cho button.
    1. Chúng ta lôi label của Button ra để thêm các Modifier để thay đổi giao diện
    1. Đây là phần code mà bên trên ta đã thêm vào mỗi label của Button

Tiếp theo, để áp dụng MyCustomButtonStyle, ta sửa lại code trong ContentView như sau:

struct ContentView: View { var body: some View { VStack(spacing: 20) { Button(action: { print("Car tapped") }) { HStack { Image(systemName: "car.fill") .font(.title) Text("Car") .fontWeight(.semibold) .font(.title) } // remove code here } .buttonStyle(MyCustomButtonStyle()) // add code here Button(action: { print("Bus tapped") }) { HStack { Image(systemName: "bus.fill") .font(.title) Text("Bus") .fontWeight(.semibold) .font(.title) } } .buttonStyle(MyCustomButtonStyle()) Button(action: { print("Bicycle tapped") }) { HStack { Image(systemName: "bicycle") .font(.title) Text("Bicycle") .fontWeight(.semibold) .font(.title) } } .buttonStyle(MyCustomButtonStyle()) } }
}

Thêm Custom Style tương đối đơn giản, chúng ta chỉ cần gọi thông qua function buttonStyle(style:_). Kết quả ta vẫn có được giống như bên trên, nhưng bây giờ code đã gọn gàng hơn nhiều, không cần phải duplicate code nữa.

Các bạn lưu ý, đoạn code thêm style đã được di chuyển ra bên ngoài, tức là viết vào View của Button, chứ không phải View của label Button nữa.

4. Custom style khi press button

Đây là câu trả lời cho câu hỏi custom style hơn gì so với Custom Modifier: Custom Style có thể thêm style của Button khi chúng ta bấm vào button, còn custom Modifier thì không.

Các bạn thêm code như sau:

struct MyCustomButtonStyle: ButtonStyle { func makeBody(configuration: Self.Configuration) -> some View { return configuration.label .frame(minWidth: 0, maxWidth: .infinity) .foregroundColor(.white) .background(LinearGradient(gradient: Gradient(colors: [Color.red, Color.yellow]), startPoint: .leading, endPoint: .trailing)) .cornerRadius(5) .padding(.horizontal, 20) // change design when press button .scaleEffect(configuration.isPressed ? 1.1 : 1.0) }
}

Bên trên, configuration có thêm property isPressed để xác định thời điểm user bấm vào button. dựa vào giá trị boolean này, ta có thể thêm style cho button tuỳ ý theo cách mình muốn. Ví dụ ở trên, tôi đã thêm code để mỗi khi user bấm vào thì button sẽ scale to ra 1 tí như hình dưới

III. Kết luận

Bên trên tôi đã giới thiệu cách tạo Custom Style cho Button trong SwiftUI, cách sử dụng và ưu/nhược điểm của Custom Style so với Custom Modifier. Hi vọng bài viết này giúp ích các bạn trong quá trình làm việc với Custom Style cho Button trong SwiftUI

Cảm ơn các bạn đã theo dõi bài viết này, have a nice day ?

Bình luận

Bài viết tương tự

- vừa được xem lúc

Học Flutter từ cơ bản đến nâng cao. Phần 1: Làm quen cô nàng Flutter

Lời mở đầu. Gần đây, Flutter nổi lên và được Google PR như một xu thế của lập trình di động vậy.

0 0 281

- vừa được xem lúc

Học Flutter từ cơ bản đến nâng cao. Phần 3: Lột trần cô nàng Flutter, BuildContext là gì?

Lời mở đầu. Màn làm quen cô nàng FLutter ở Phần 1 đã gieo rắc vào đầu chúng ta quá nhiều điều bí ẩn về nàng Flutter.

0 0 206

- vừa được xem lúc

Swift: Tạo custom phép toán tử (Operator) của riêng bạn!

Swift cho phép bạn tạo các toán tử có thể tùy chỉnh của riêng bạn. Điều này đặc biệt hữu ích khi bạn xử lý các loại dữ liệu của riêng mình. Operator Types in Swift. Có năm loại toán tử chính trong Swift.

0 0 56

- vừa được xem lúc

Chương 6 Protocol oriented programming.

Cuốn sách này là về lập trình hướng protocol. Khi Apple thông báo swift 2 ở WWDC 2015.

0 0 46

- vừa được xem lúc

Ví dụ về UIActivityViewController

Trên iOS, UIActivityViewController cung cấp giao diện thống nhất để người dùng chia sẻ và thực hiện các hành động trên văn bản, hình ảnh, URL và các mục khác trong ứng dụng. let string = "Hello, world!". let url = URL(string: "https://nshipster.com").

0 0 58

- vừa được xem lúc

Quản lý self và cancellable trong Combine.

. . Công việc quản lý bộ nhớ memory management thường trở nên phức tạp khi chúng ta thực hiện các tác vụ bất đồng bộ asynchronous vì chúng ta thường phải lưu giữ một số object nằm ngoài scope mà object được define trong khi vẫn phải đảm bảo được việc giải phóng object đó được thực hiện đúng quy trìn

0 0 41