มารู้จัก IBInspectable / IBDesignable กันหน่อย

IBInspectable / IBDesignable คือ Keyword ที่เอาไว้บ่งบอกถึงการนำ Custom View ไป Render บน Interface Builder

หลายคนอาจจะเคยสร้าง Custom view ด้วย Xib มาก่อน แล้วก็มักจะพบกับปัญหาว่า เวลาที่เอา View ไปใส่ใน ViewController แต่มันไม่มีการ Render ใน Interface Builder ให้ แต่ขึ้น View ว่างเปล่าเอาไว้เฉยๆ ซึ่งบางครั้งคนที่มาพัฒนาต่อหรือเราเองนิแหละที่ทำเสร็จไปนานแล้วแล้วต้องกลับมาแก้ไข ก็อาจจะงงว่า View นี้มันคือ View อะไรนะ ซึ่งวันนี้จะทำให้ดูว่าวิธีการทำให้ Interface Builder มัน Render View เค้าทำกันยังไง

แต่ก่อนอื่นเลยก่อนที่เราจะมาทำความรู้จักกับการ Render View นั้น เราต้องมาทำการสร้าง Custom view ที่จะเอาไปใช้ใน Project กันก่อนครับ ซึ่งผมได้เขียนบทความเอาไว้ก่อนหน้านี้แล้วถ้าใครทำไม่เป็นก็แนะนำให้ไปอ่านก่อนนะครับ Custom Viewคลิกไปอ่านเลย

Custom view ที่จะเอามาสอนในครั้งนี้ครับ

+++ มาลุยกันเลย +++

IBDesignable

Keyword นี้เอาไว้บอก Interface Builder ให้นำ UI ไป Render โดยปกติถ้าเราไม่ได้ใช้ Keyword นี้เวลาเรานำ Custom View ไปใส่ใน Interface Builder นั้นมันจะไม่มีการ Render View ขึ้นมาให้ แต่ถ้าเราอยากเห็นก็ต้องเอามันไปใส่ไว้หน้า Class นั้น

รูปนี้คือตอนที่ยังไม่ได้เอา @IBDesignable มาเติมต่อหน้า Class ใน Interface Builder ก็จะเห็นเป็น View โง่ๆธรรมดา View นึงที่มีการเปลี่ยนสีพื้นหลังไป

แต่เมื่อเรานำ IBDesignable ไปใส่ไว้หน้า Class ที่ต้องการ Render View ใน Interface Builder ก็จะได้ผลดังรูปด้านล่าง

ด้านล่างนี้เป็นตัวอย่างการใช่ IBDesignable (ให้นำมาเติมไว้หน้า Class ที่ต้องการ)

@IBDesignable class ProfileView: UIView {}

แล้วถ้าอยากแก้ไขข้อความหน่อยละทำได้ไหม?

ก่อนอื่นเลยเราต้องทำการ Override prepareForInterfaceBuilder แล้วถ้าอยากจะแก้ไขอะไรก็แก้ได้เลยครับ

override func prepareForInterfaceBuilder(){
lblName.text = "Piyawut Kamwiset"
lblPhoneNumber.text = "081-XXX-XXXX"
imageProfile.backgroundColor = UIColor.blue
}

กลับมาดูที่ Interface Builder กันครับ

เมื่อได้ทำการ Override แล้วเมื่อแก้ไขข้อความหรืออื่นๆ มันจะสามารถแสดงสิ่งที่เราต้องการได้เลย

ถ้า Interface Builder มันไม่ Render หรือมี Error เราจะทำไรได้มั่งละ ?

  • ถ้าต้องการ Render view ใหม่อีกรอบเราสามารถกด Editor -> Refresh All Views แล้วรอมัน Render แปบนึงครับ
  • แต่ถ้ามีการแจ้งว่าพบ Error เกิดขึ้น เราสามารถใช้ Editor -> Debug Selected Views มันจะทำการ Run แล้วบอกว่ามี Error ตรงไหน
รูปแสดงวิธี Render และ Debug view

อะไรกันมีแค่นิเองหรอยังไม่เห็น WOW เลย

ถ้าเราอยากจะใส่พวก Corner, Border หรืออื่นๆ แล้วให้มันไปแสดงใน Interface Builder เลยได้ไหมละ มันไม่ใช่เรื่องยากเลย คำตอบของคำถามอยู่ที่ IBInspectable Keyword

IBInspectable Keyword ?

IBInspectable คือ keyword ที่จะทำให้เราเพิ่ม Attributes ใน Identity Inspector ได้อย่างง่ายดายมากๆ

เพียงแค่เราสร้างตัวแปรขึ้นมา (วิธีสร้างเหมือนกับการประกาศตัวแปรทั่วไป แต่ต้องเติม @IBInspectable ไว้หน้าตัวแปรด้วย) แล้วเมื่อตัวแปรมีการอัพเดทค่าเราก็ให้มันทำหน้าที่ที่เราต้องการออกมา

ยกตัวอย่าง ถ้าเราอยากใส่ Cornerให้กับ imageProfile

@IBInspectable var imageProfileCornerRadius: CGFloat = 0  {
didSet{
imageProfile.layer.cornerRadius = imageProfileCornerRadius
}
}

ถ้าลองสังเกตดีๆ เราจะเห็น Attribute ที่เพิ่มขึ้นมา ชื่อก็จะตรงกับที่เราตั้งไว้ใน Code เลย แล้วพอเราเปลี่ยนค่าใน Attribute นั้นๆ UI ก็จะ update ให้เองเลย ดูดีไหมละ
ไหนอะเราลองมาเปลี่ยนค่ากันดีกว่า

เห็นความเปลี่ยนแปลงใน Interface Builder ไหมครับพอเราเปลี่ยน Corner Radius แล้ว UI ก็มีการ Update ให้เลย ที่นิเราก็ไม่ต้องมามโนว่ามันสวยแล้วหรือยัง หรือต้องมา Run Application จริงๆให้เสียเวลากันเปล่าๆ

แต่อย่าเพิ่งดีใจไปครับการมีข้อดีมันก็จะมีข้อเสียมาคู่กันเสมอ

ข้อเสียของการใช้ IBDesignable และ IBInspectable

  • เมื่อเราใช้ IBDesignable และ IBInspectable มันจะทำให้เวลาเราเปิด Inerface Builder ขึ้นมา มันจะรันนานมากๆ ซึ่งมันก็ทำให้น่ารำคาญได้เหมือนกันกับคอมที่ช้าๆ
  • IBInspectable ก็ไม่ได้ลองรับที่ Class ได้ทั้งหมดนะ เราสามารถใช้ได้แค่ Int , CGFloat , Double , String , Bool , CGPoint , CGSize , CGRect , UIColor , UIImage เท่านั้นเอง

ข้อดีของการใช้ IBDesignable และ IBInspectable

  • ทำให้เราไม่ต้องไปมโนว่าเราต้องปรับความโค้งมนให้กับ UI เราตรงไหนไหม
  • ทำให้เราเห็น UI บน Inerface Builder คล้ายของจริงมากที่สุด

ได้เห็นข้อดี ข้อเสียและวิธีการใช้กันไปแล้ว ที่เหลือก็แล้วแต่ Developer เลยครับว่าชอบการทำงานกันแบบไหน ขอให้สนุกกับการใช้ IBDesignable และ IBInspectable กันนะครับ

อันนี้เป็นตัวอย่าง Code ครับ