2016-11-13 17 views
6

Tôi đã cố gắng tìm ra cách tạo chế độ xem tùy chỉnh bằng cách sử dụng các tệp xib. Trong question phương pháp tiếp theo này được sử dụng.Swift 3 Tải xib. NSBundle.mainBundle(). LoadNibNamed return Bool

NSBundle.mainBundle().loadNibNamed("CardView", owner: nil, options: nil)[0] as! UIView 

Cocoa có cùng một phương pháp, tuy nhiên, phương pháp này đã thay đổi trong nhanh chóng 3-loadNibNamed(_:owner:topLevelObjects:), mà lợi nhuậnBool và mã trước tạo "Loại Bool không có thành viên subscript" lỗi, mà là hiển nhiên, vì kiểu trả về là Bool.

Vì vậy, câu hỏi của tôi là làm thế nào để một cái nhìn load từ file xib trong Swift 3

Trả lời

8

Trước hết phương pháp này chưa được thay đổi trong Swift 3.

loadNibNamed(_:owner:topLevelObjects:) đã được giới thiệu trong macOS 10.8 và hiện diện trong tất cả các phiên bản của Swift. Tuy nhiên loadNibNamed(nibName:owner:options:) đã được giảm xuống trong Swift 3.

Chữ ký của phương pháp này là

func loadNibNamed(_ nibName: String, 
         owner: Any?, 
      topLevelObjects: AutoreleasingUnsafeMutablePointer<NSArray>?) -> Bool 

vì vậy bạn phải tạo ra một con trỏ để lấy các mảng của các quan điểm về lợi nhuận.

var topLevelObjects = NSArray() 
if Bundle.main.loadNibNamed("CardView", owner: self, topLevelObjects: &topLevelObjects) { 
    let views = (topLevelObjects as Array).filter { $0 is NSView } 
    return views[0] as! NSView 
} 

Chỉnh sửa: Tôi đã cập nhật câu trả lời để lọc ví dụ NSView đáng tin cậy.


Trong Swift 4 cú pháp hơi thay đổi và sử dụng first(where là hiệu quả hơn:

var topLevelObjects : NSArray? 
if Bundle.main.loadNibNamed(assistantNib, owner: self, topLevelObjects: &toplevelObjects) { 
    return topLevelObjects!.first(where: { $0 is NSView }) as? NSView 
} 
+0

Trên một dòng, hãy xem = topLevelObjects [0] as! NSView - Tôi gặp lỗi "Không thể truyền giá trị kiểu 'NSApplication' (0x7fffd8201278) đến 'NSView' (0x7fffd8210048)." – Alex

+0

Gọi phương thức này giả định rằng có một tệp nib/xib chứa một dạng xem là đối tượng cấp cao nhất. – vadian

+0

Cảm ơn, đã tìm thấy một sai lầm. – Alex

2

Swift 4 phiên bản của câu trả lời @ vadian của

var topLevelObjects: NSArray? 
if Bundle.main.loadNibNamed(NSNib.Name(rawValue: nibName), owner: self, topLevelObjects: &topLevelObjects) { 
    return topLevelObjects?.first(where: { $0 is NSView }) as? NSView 
} 
0

tôi đã viết một phần mở rộng an toàn và dễ tải từ nib:

extension NSView { 
    class func fromNib<T: NSView>() -> T? { 
     var viewArray = NSArray() 
     guard Bundle.main.loadNibNamed(String(describing: T.self), owner: nil, topLevelObjects: &viewArray) else { 
      return nil 
     } 
     return viewArray.first(where: { $0 is T }) as? T 
    } 
} 

Sau đó, chỉ cần sử dụng như thế này:

let view: CustomView = .fromNib() 

CustomView là một lớp con NSView và cũng CustomView.xib.

Các vấn đề liên quan