2017-01-24 50 views
6

Obecnie aktualizuję projekt, aby korzystać z image literals, aby czerpać korzyści z nieobowiązkowych obrazów. Projekt importuje różne frameworki, a frameworki zawierają obrazy.Xcode8: Użycie literałów obrazkowych w frameworkach

W ramach, musieliśmy zadeklarować rozszerzenie na UIImage, aby zastąpić inicjator, ponieważ szukało obrazu w niewłaściwym pakiecie. Zrobiliśmy coś takiego:

extension UIImage { 
    convenience init?(framework_named imageName: String) { 
     let bundle = Bundle(for: ClassNameInFramework.self) 
     self.init(named: imageName, in: bundle, compatibleWith: nil) 
    } 
} 

Ja chce używać literały graficznych w ramach też, ale jak wcześniej, literały szukasz niewłaściwym wiązki dla obrazu i zastosowanie wywala.

Czy ktoś wie, jak określić literał obrazu, do którego pakunku należy szukać obrazu?

+1

Nie można określić niestety. Litery obrazowe wywołują inicjator 'init (named:)', który wygląda w głównym pakiecie. – dan

+1

@dan Czy mógłbyś wskazać mi jakąś dokumentację? – dirtydanee

Odpowiedz

3

Odkryłem całkiem proste obejście i byłem zaskoczony, że nie znalazłem go nigdzie w innych postach. Chciałbym, żeby było bardziej elegancko, ale jest to lepsze niż używanie brzydkiego inicjału opartego na stringach.

My w zasadzie wykorzystać protokół _ExpressibleByImageLiteral, która jest co Xcode używa do określenia, czy typ jest eksprymowanej przez obrazie dosłowne, jak w przykładzie:

struct WrappedBundleImage: _ExpressibleByImageLiteral { 
    let image: UIImage 

    init(imageLiteralResourceName name: String) { 
     let bundle = Bundle(for: ClassInFramework.self) 
     image = UIImage(named: name, in: bundle, compatibleWith: nil)! 
    } 
} 

Należy pamiętać, że używam otoki zamiast UIImage podklasa, która wydaje się lepszą opcją. Niestety, klasy takie jak UIImage nie mają być poddane podklasie i jeśli się to stanie, dostaniesz wiele bólu głowy.

A teraz jego użycie staje:

let image = (as WrappedBundleImage).image 

Nie tak zwięzły jak normalny obraz dosłowne, ale nadal, sprawdzane w czasie kompilacji :). Musimy tylko pamiętać o wykonaniu odlewu as, w przeciwnym razie nasz inicjator niestandardowy nie zostanie wywołany.

Można też zrobić coś takiego:

extension UIImage { 
    static func fromWrappedBundleImage(_ wrappedImage: WrappedBundleImage) -> UIImage { 
     return wrappedImage.image 
    } 
} 

I możemy teraz używać go tak:

UIImage.fromWrappedBundleImage() 

nadzieję, że to pomaga!

+0

To całkiem fajne, stary. –

+0

Dzięki @pallzoltan, też tak myślę. Nie rozumiem, dlaczego ludzie głosują w dół na odpowiedź. Tak, może nie jest tak ładna jak zwykłe używanie normalnego obrazu, ale jest sprawdzana w czasie kompilacji, więc o wiele bezpieczniejsza niż wywołanie UIImage (o nazwie: in: compatibleWith:) ... Moim zdaniem, to jest coś więcej niż użycie "named: in: compatible" z inicjatorem tylko dlatego, że nie chce używać protokołu _ExpressibleByImageLiteral, który nie jest zbyt tajemniczy (zachowuje się dokładnie tak jak inne protokoły ExpressibleBy). Zawsze chcesz zapobiec problemom w środowisku wykonawczym, szczególnie w ramach ... – diegomontoyas