2017-01-24 5 views
6

В настоящее время я обновляю проект, чтобы использовать image literals, чтобы пользоваться преимуществами не факультативных изображений. Проект импортирует различные структуры, а рамки содержат изображения.Xcode8: Использование литератур изображений в фреймах

В рамках мы должны были объявить расширение на UIImage, чтобы переопределить инициализатор, потому что он искал изображение в неправильном комплекте. Мы сделали что-то вроде:

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

Я хотел использовать литералы изображения в рамках тоже, но, как и прежде, литералы ищут неверный пучок для изображения и приложения падает.

Кто-нибудь знает, как указать литеральное изображение, к которому требуется найти изображение?

+1

Не могу указать, к сожалению. Литералы изображений вызывают инициализатор 'init (named:)', который выглядит в основном пакете. – dan

+1

@ dan Вы могли бы указать мне какую-нибудь документацию? – dirtydanee

ответ

3

Я обнаружил довольно простой обходной путь и был поражен, чтобы не найти его нигде на других постах. Я бы хотел, чтобы он был более изящным, но предпочтительнее, чем использовать уродливый UIImage(named:in:compatibleWith:) строгий типизированный инициализатор, на мой взгляд.

Мы в основном воспользоваться протоколом _ExpressibleByImageLiteral, который является тем, что использует Xcode, чтобы определить, является ли тип выразимые изображений буквальный, например, так:

struct WrappedBundleImage: _ExpressibleByImageLiteral { 
    let image: UIImage 

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

Обратите внимание, что я использую обертку вместо UIImage подкласс, который будет казаться лучшим вариантом. К сожалению, классы, такие как UIImage, не предназначены для подкласса, и если вы это сделаете, вы получите много головных болей.

И теперь его использование становится:

let image = (as WrappedBundleImage).image 

Не так, как сжатое нормальное изображение буквального, но все же, время компиляции проверяется :). Мы просто должны помнить о том, чтобы сделать кастинг as, иначе наш пользовательский инициализатор не будет вызван.

Вы также можете сделать что-то вроде этого:

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

И теперь мы можем использовать его как это:

UIImage.fromWrappedBundleImage() 

Надеются, что это помогает!

+0

Это довольно круто, человек. –

+0

Спасибо @pallzoltan, я тоже так думаю. Я не понимаю, почему люди голосуют за ответ. Да, возможно, это не так хорошо, как просто использовать литерал изображения нормально, но он проверяется временем, поэтому гораздо безопаснее, чем вызов UIImage (named: in: compatibleWith:) ... На мой взгляд, это стоит больше, чем использовать инициализатор «named: in: compatibleWith» просто из-за того, что не хочет использовать протокол _ExpressibleByImageLiteral, который не очень таинственный (ведет себя точно так же, как и другие протоколы ExpressibleBy). Вы всегда хотите предотвратить проблемы во время выполнения, особенно в рамках ... – diegomontoyas

Смежные вопросы