Tạo Text Field với hiệu ứng đếm kí tự (Phần 2)

38

Bước 3: Đếm các kí tự của Chuỗi

Cùng xem trước project và xem thử nó sẽ đếm kí tự như thế nào:

1-asxm0IJLpznKQeTU8CiaQQ

Chúng ta cần chỉnh Chuỗi đếm thành cấu hình: currentCount/Limit

Số kí tự hiện tại chính là độ dài Chuỗi mà chúng ta nhập vào. Nhưng làm cách nào để biết?

Cách dễ dàng nhất đó là truy cập vào Chuỗi đó và lấy số kí tự của nó:

Cách khác đó là truy cập UTF16 kí tự đếm:

UTF16.count trả về số kí tự Unicode, còn characters.count trả về số 16 bits. Ở đây chúng ta sẽ sử dụng cách UTF16.

Quay lại hàm initialCounterLabel : nó sẽ lấy optional String như là một biến, do đó để truy cập giá trị này chúng ta cần safe-unwrap nó. Thêm dòng lệnh sau vào trong hàm initialCounterLabel :

Khi đã có giá trị chuỗi unwrapped, chúng ta cần định dạng initialCounterLabel. Nếu giá trị của text là nil, chúng ta sử dụng “0” cho biến đếm:

Bước cuối cùng của định dạng biến đếm sẽ là gọi setCountLabel(). Thêm đoạn lệnh này vào cuối cùng của class:

Chúng ta không cần thiết lập label, nếu lengthLimit là 0 thì kiểm tra và gọi setCounterLabel() như ví dụ dưới đây:

Chúng ta đã tạo xong Counter Label và thiết lập giá trị mặc định khi nó xuất hiện. Nếu bạn build và run project của bạn, bạn sẽ thấy như hình này:

1-WtNfwD9hlZLs6MPJQMApOgĐến đây Counter Label của chúng ta vẫn chưa có.

Như tác giả đã nhắc ở trên, giá trị mặc định của rightView là nil, nên frame của nó cũng sẽ là nil. Để khởi tạo một frame mới chúng ta cần override hàmrightViewRectForBounds của UITextField. Thêm đoạn lệnh ở cuối class của bạn:

Nếu lengthLimit = 0, chúng ta không cần tạo frame vì vậy chỉ cần trả về CGRect()

Tác giả thiết lập frame là 35 points tính từ phía bên phải của supervieư và làm frame này rộng 30 points. Nó sẽ cách cạnh phải là 5 points, đó là những gì chúng ta sẽ cần sau cho animation.

Build và run project và chúng sẽ thấy được những gì đã mong muốn:

1-Hpc9mCajfdx5Np5Zp2Bguw

Chúng ta đã gần hoàn thành xong hết. Ở phần cuối chúng ta sẽ kiểm tra độ dài hiện tại, hiển thị biến đếm, giới hạn nó và cho biết phản hồi trực quan.

Bước 4: Do the Magic!

Như tác giả đã nêu ở trên răng bài hướng dẫn này rất là cơ bản, chúng ta cần override hàm UITextFieldDelegate. Hơn nữa, class của chúng ta sẽ không conform với UITextFieldDelegate, nên chúng ta sẽ tạo một class extension:

Đừng quên thiết lập delegate là self, để class của chúng ta sử dụng delegate này. Thêm dòng lệnh này trong hàm awakeFromNib():

Chúng ta sẽ override hàm shoutChangeCharacterInRange . Nó sẽ được gọi mỗi khi bạn nhập hoặc xoá 1 kí tự trong text field, và trước khi kí tự đó xuất hiện trên UITextField. Hàm này sẽ trả về giá trị Boolean, nên chúng ta cần nghĩ nó như là một công tắc on/off. Nếu nó trả về true, thì text field sẽ hiện sự thay đổi. Nếu nó trả về false, nó sẽ không thay đổi những gì đã nhập, không có chuyện gì xảy ra nếu bạn nhập tiếp.

Thêm hàm này vào trong class extension đã tạo hồi nãy:

Đừng lo về việc compiler bị lỗi, nó sẽ hết một khi chúng ta trả về giá trị Boolean từ hàm này.

Đầu tiền, chúng ta đặt guard trước câu lệnh để kiểm tra, nếu nó có giá trị của trong textField. Nhập dòng code này vào trong hàm:

Nếu cú pháp guard sai, chúng ta trả về true, nghĩa là giá trị hiện tại trong textField được cho phép. Chúng ta cũng cần phải chắc chắn răng giá trị của lengthLimit là một số khác 0.

Tiếp theo, tính toán chiều dài của đoạn text hiện tại:

Trong dòng lệnh này:

  • text.utf16.count là số kí tự hiện tại lúc bạn chưa nhập.
  • string.utf16.count là số kí tự bạn vừa nhập vừa.
  • range.length là số kí tự bạn đã xoá.

Chúng ta sử dụng newLength là chuỗi thu được sau khi đã giới hạn:

Chúng ta cần làm một hiệu ứng khi các kí tự đạt tới giới hạn. Để làm điều này, chúng ta cần phải tạo một vài hiệu ứng đơn giản, thêm đoạn code dưới đây vào sau else phía trên:

Đây là những gì đoạn code hiệu ứng hình ảnh đã làm:

  1. Tạo 1 UIViewAnimation với độ trễ là 0.1 giây.
  2. Việc chuyển đổi hiệu ứng của label dựa vào 2 trục X và Y. Chúng ta thiết lập các frame của counter label phù hợp với tỉ lệ của hiệu ứng.
  3. Khi một hiệu ứng được hoàn thành, tạo một hiệu ứng khác với độ trễ tương tự.
  4. Hiệu ứng của label trở lại kích thước ban đầu.

Cuối cùng, chúng ta cần trả về giá trị cho shouldChangeCharactersInRange() là Boolean. Chúng ta sử cho phép cập nhật textField nếu độ dài kí tự hiện tại nằm trong giới hạn. Thêm dòng lệnh này vào cuối hàm:

Nó sẽ trả về là true nếu chuỗi ngắn hơn độ dài mà người dùng đặt ra.

Nguồn IDE Academy via Medium via Github