【问题标题】:Is any function in swift similar to R.java in Android?swift中的任何功能是否类似于Android中的R.java?
【发布时间】:2016-08-08 07:03:53
【问题描述】:

我是 iOS 初学者,速度很快。

我曾经编写过 Android,我认为 R.java 是管理 id、drawable、字符串和其他资源的好主意。 所以我很惊讶iOS没有提供好的访问资源的功能。

如果我想从资产中获取图片,我会调用UIImage(named: "img_name"),但我认为这不是访问img_name 的最佳方式,我可能使用了错误的名称而无法获取图片.

我发现了一些像SharkSwiftGen这样的开源项目,但是Shark只支持图像,SwiftGen似乎需要不自动运行命令。

您有更好的解决方案吗?谢谢!

【问题讨论】:

    标签: android ios swift r.java-file


    【解决方案1】:

    我有一个开源项目R.swift-plugin,它提供了您提到的功能。您只需要通过Alcatraz 安装Xcode Plugin 并搜索R.swift

    插件会自动生成一个资源文件来管理你的图片、可本地化的字符串和颜色,你可以像使用 R.java 一样访问它们

    用法:

    真诚推荐您尝试一下。并随时给我任何改进它的建议:)

    【讨论】:

    • 它看起来绝对是我想要的!但只支持字符串、图像、颜色。反正我会试试的。
    • 是的,我认为字符串、图像和颜色应该是最常见的资源。
    • 但是我打算以后让它支持 id(reuseidentifier, segue), layout(nib), bool, dimen 和 integer!我真的希望这个插件会有所帮助。
    • 请注意,虽然这个“R.swift-plugin”使用了一个非常相似的名称,但它与R.swift 工具无关。
    【解决方案2】:
    • 如果您使用InterfaceBuilder(也称为Storyboardxib),则无需为每个视图定义id。您可以在代码中bind outlets。

    • 如果您想使用其 id 检索视图(如您所要求的 R.java),您可以为每个视图设置标签并在代码中操作它们。

    与 AndroidStudio 不同,Xcode不会生成任何文件。

    func viewDidLoad() {
        let labelView = self.view.viewWithTag(0) as? UILabel
    }
    

    【讨论】:

    • 谢谢。但它只支持 ids 和 layouts 对吧?有没有管理图像、颜色或字符串的功能?
    • 将图像添加到 Xcode 中的 Assets 文件夹。通常,只需添加 3 倍图像即可正确显示和缩放。 UIImage(named: "hello") 将从Assets 检索名为hello 的图像。
    • 可以,但是使用图片名称初始化可能会因为错字而失败
    • @FindleyTyler 是的,你是对的。但是,在 Swift 中有一个特殊的泛型类型,叫做Optional。默认情况下,所有类型和类都是 nil “不兼容的”。这意味着,您不能将 nil 分配为值并且编译代码会失败。 Optional 使它们可分配,因此您的应用程序不会崩溃,除非您强制解开它们。这里有更多信息。 stackoverflow.com/a/24026093/3815843
    • 另外,UIImageView 的属性image 的类型为UIImage?,这意味着Optional<UIImage>。您可以将nil 分配给image,视图将不会呈现任何内容。因此,如果您希望看到一些图像,但您没有看到任何内容,则可能是您打错了
    【解决方案3】:

    Xcode 本身没有这样的功能,但是有一个开源项目可以做到这一点:R.swift

    它会自动更新生成的文件并支持许多不同的资源类型,例如图像、字体、segues 等等。

    【讨论】:

    • 安装步骤看起来好复杂。但这似乎是一个很好的解决方案。
    【解决方案4】:

    您可以通过使用扩展和枚举来获得类似的功能。

    使用枚举可以避免拼写错误并受益于 Xcode 的自动建议/自动完成功能。

    UIImage 示例:

    extension UIImage {
    
        enum ImageId: String {
            // These are your images NAMES,
            // as in "SpriteMonster.jpg"
            case SpriteMonster, SpriteHero, BaseLandscape
        }
    
        convenience init!(id: ImageId) {
            self.init(named: id.rawValue)
        }
    }
    

    用法:

    let monster = UIImage(id: .SpriteMonster)  // the "SpriteMonster.jpg" image
    

    对于这个例子,我强制解开便利初始化,所以要小心在你的包中实际使用正确名称的图像。

    对于字符串:

    extension String {
    
        enum StringId: String {
            case Welcome = "Welcome to the game!"
            case GameOver = "You loose! Game over!"
        }
    
        init(id: StringId) {
            self = id.rawValue
        }
    
    }
    

    用法:

    let label = String(id: .Welcome) // "Welcome to the game!"
    

    对于字体:

    extension UIFont {
    
        enum FontId {
            case HelveticaNeueLarge
            case HelveticaNeueMedium
            case HelveticaNeueSmall
    
            func font() -> UIFont {
                switch self {
                case .HelveticaNeueLarge:
                    return UIFont(name: "HelveticaNeue", size: 18)!
                case .HelveticaNeueSmall:
                    return UIFont(name: "HelveticaNeue", size: 12)!
                default:
                    return UIFont(name: "HelveticaNeue", size: 14)!
                }
            }
        }
    
        class func get(id: FontId) -> UIFont {
            return id.font()
        }
    
    }
    

    用法:

    let font = UIFont.get(.HelveticaNeueLarge) // <UICTFont: 0x7ffd38f09180> font-family: "Helvetica Neue"; font-weight: normal; font-style: normal; font-size: 18.00pt
    

    这些只是演示概念的示例,您可以进一步了解这一点。

    【讨论】:

      猜你喜欢
      • 2021-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-11
      • 2011-12-29
      • 2013-04-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多