Saya ingin membuat @IBInspectable
elemen seperti yang Anda lihat pada gambar di bawah ini:
ide saya adalah menggunakan sesuatu seperti enum sebagai tipe untuk @IBInspectable
, tapi sepertinya bukan itu masalahnya, ada ide bagaimana mengimplementasikan elemen seperti ini?
EDIT:
Sepertinya @IBInspectable
hanya mendukung jenis ini:
Int
CGFloat
Double
String
Bool
CGPoint
CGSize
CGRect
UIColor
UIImage
kekecewaan
Jawaban:
Itu tidak mungkin (untuk saat ini). Anda hanya dapat menggunakan jenis yang Anda lihat di bagian Atribut Waktu Proses yang Ditentukan Pengguna .
Dari dokumen Apple :
sumber
Solusi lain untuk ini adalah mengubah bagaimana properti enumerasi muncul ke pembuat antarmuka. Sebagai contoh:
#if TARGET_INTERFACE_BUILDER @property (nonatomic, assign) IBInspectable NSInteger fontWeight; #else @property (nonatomic, assign) FontWeight fontWeight; #endif
Ini mengasumsikan enum yang disebut FontWeight. Ini bergantung pada fakta bahwa enum dan nilai integer mentahnya dapat digunakan secara bergantian di Objective-C. Setelah melakukan ini, Anda dapat menentukan bilangan bulat dalam Pembuat antarmuka untuk properti yang tidak ideal, tetapi berfungsi, dan mempertahankan sejumlah kecil keamanan tipe saat menggunakan properti yang sama secara terprogram.
Ini adalah alternatif yang lebih baik daripada mendeklarasikan properti integer terpisah karena Anda tidak perlu menulis logika tambahan untuk menangani properti integer kedua yang juga dapat digunakan untuk mencapai hal yang sama.
Namun, ini tidak berfungsi dengan Swift karena kami tidak dapat secara implisit mentransmisikan dari integer ke enum. Pikiran apa pun tentang pemecahan yang akan dihargai.
sumber
Saya melakukan ini menggunakan nilai Inspectable NSInteger dan menimpa penyetel untuk memungkinkannya menyetel enum. Ini memiliki batasan untuk tidak menggunakan daftar popup dan jika Anda mengubah nilai enum Anda, maka opsi antarmuka tidak akan diperbarui untuk mencocokkan.
Contoh.
Di File Header:
typedef NS_ENUM(NSInteger, LabelStyle) { LabelStyleContent = 0, //Default to content label LabelStyleHeader, }; ... @property LabelStyle labelStyle; @property (nonatomic, setter=setLabelAsInt:) IBInspectable NSInteger labelStyleLink;
Dalam file implementasi:
- (void)setLabelAsInt:(NSInteger)value { self.labelStyle = (LabelStyle)value; }
Anda dapat secara opsional menambahkan beberapa logika di sana untuk memastikan bahwa itu disetel ke nilai yang valid
sumber
Sikhapol benar, enum belum didukung juga tidak di xCode 9. Saya percaya pendekatan teraman adalah dengan menggunakan enum sebagai string dan menerapkan var IBInspectable "bayangan" (pribadi). Berikut adalah contoh item BarBtnPaintCode yang merepresentasikan item barbutton yang dapat diberi gaya dengan ikon kustom (yang dilakukan menggunakan PaintCode) tepat di dalam Interface Builder (swift 4).
Dalam membangun antarmuka Anda cukup memasukkan string (identik dengan nilai enum), yang membuatnya tetap jelas (jika Anda memasukkan angka tidak ada yang tahu apa artinya)
class BarBtnPaintCode: BarBtnPaintCodeBase { enum TypeOfButton: String { case cancel case ok case done case edit case scanQr //values used for tracking if wrong input is used case uninitializedLoadedFromStoryboard case unknown } var typeOfButton = TypeOfButton.uninitializedLoadedFromStoryboard @IBInspectable private var type : String { set { typeOfButton = TypeOfButton(rawValue: newValue) ?? .unknown setup() } get { return typeOfButton.rawValue } } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) setup() } init(typeOfButton: TypeOfButton, title: String? = nil, target: AnyObject?, action: Selector) { super.init() self.typeOfButton = typeOfButton setup() self.target = target self.action = action self.title = title } override func setup() { //same for all setTitleTextAttributes([NSAttributedStringKey.font : UIFont.defaultFont(size: 15)],for: UIControlState.normal) //depending on the type switch typeOfButton { case .cancel : title = nil image = PaintCode.imageOfBarbtn_cancel(language: currentVisibleLanguage) case .ok : title = nil image = PaintCode.imageOfBarbtn_ok(language: currentVisibleLanguage) case .done : title = nil image = PaintCode.imageOfBarbtn_done(language: currentVisibleLanguage) case .edit : title = nil image = PaintCode.imageOfBarbtn_edit(language: currentVisibleLanguage) case .uninitializedLoadedFromStoryboard : title = nil image = PaintCode.imageOfBarbtn_unknown break case .unknown: log.error("BarBtnPaintCode used with unrecognized type") title = nil image = PaintCode.imageOfBarbtn_unknown break } } }
sumber
Seperti yang dijawab oleh @sikhapol, hal itu tidak mungkin. Solusi yang saya gunakan untuk ini adalah memiliki banyak
IBInspectable
kelemahan di kelas saya dan cukup pilih satu di pembuat antarmuka. Untuk keamanan tambahan yang beberapa tidak disetel, tambahkanNSAssert
penyetel untuk masing-masing.- (void)setSomeBool:(BOOL)flag { if (flag) { NSAssert(!_someOtherFlag && !_someThirdFlag, @"Only one flag can be set"); } }
Ini IMO sedikit membosankan dan sedikit ceroboh, tapi itu satu-satunya cara untuk mencapai perilaku seperti ini yang dapat saya pikirkan.
sumber
Saya ingin menambahkan bahwa pengenal an
enum
tidak tersedia pada waktu proses untuk siapa pun di Objective-C. Jadi tidak mungkin untuk menampilkannya dimanapun.sumber
Solusi saya adalah melakukan:
@IBInspectable var keyboardType = UIKeyboardType.default.rawValue { didSet { textField.keyboardType = UIKeyboardType(rawValue: keyboardType)! } }
Di IB itu sendiri, Anda perlu menyetel int di bidang keyboardType
sumber