标签: swift-protocols

SwiftUI,在 @Viewbuilder 中将视图作为参数传递

我的好奇心促使我将View类型作为参数传递给@ViewBuilder. 将模型/基元类型作为参数传递@ViewBuilder是完全有效的。

如下代码所示。

struct TestView<Content: View>: View {
    
    let content: (String) -> Content
    
    init(@ViewBuilder content: @escaping (String) -> Content) {
        self.content = content
    }
    
    var body: some View {
        content("Some text")
    }
}

struct ContentTestView: View {
    
    var body: some View {
        TestView {
            Text("\($0)")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

代替String

let content: (String) -> Content
Run Code Online (Sandbox Code Playgroud)

如果我尝试传递 SwiftUIView类型,则编译器对此不满意。

let content: (View) -> Content
Run Code Online (Sandbox Code Playgroud)

尽管 params for@ViewBuilder接受自定义协议类型Searchable,但不接受View协议。 …

struct ios swift-protocols swiftui viewbuilder

6
推荐指数
1
解决办法
4672
查看次数

Swift:无法为协议属性赋值?

A类提供字符串值.B类本身有两个A类成员,并提供计算属性"v"来选择其中一个.

class A {
    var value: String

    init(value: String) {
        self.value = value
    }
}

class B {
    var v1: A?
    var v2: A = A(value: "2")

    private var v: A {
        return v1 ?? v2
    }

    var value: String {
        get {
            return v.value
        }
        set {
            v.value = newValue
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这段代码很简单,很有效.由于A和B都有一个成员"值",我把它作为这样的协议:

protocol ValueProvider {
    var value: String {get set}
}

class A: ValueProvider {
    var value: String

    init(value: String) {
        self.value = value
    }
}

class …
Run Code Online (Sandbox Code Playgroud)

properties ios swift swift-protocols

5
推荐指数
1
解决办法
2069
查看次数

以面向协议的方式实施活动指示器

我想创建协议,当它们符合此协议时,它将使我能够向UIViewController及其子类添加活动指示符/从UIViewController及其子类中移除活动指示符。

所以我最终得到了这样的代码

protocol ActivityIndicatorPresenter {
    var activityIndicator: UIActivityIndicatorView { get }
    func showActivityIndicator()
    func hideActivityIndicator()
}

extension ActivityIndicatorPresenter where Self: UIViewController {
    func showActivityIndicator() {
        dispatch_async(dispatch_get_main_queue()) {
            self.activityIndicator.color = UIColor.blackColor()
            self.activityIndicator.frame = CGRect(x: 0.0, y: 0.0, width: 80.0, height: 80.0)
            self.activityIndicator.center = CGPoint(x:self.view.bounds.size.width / 2, y:self.view.bounds.size.height / 2)
            self.view.addSubview(self.activityIndicator)
            self.activityIndicator.startAnimating()
    }
}

    func hideActivityIndicator() {
        dispatch_async(dispatch_get_main_queue()) {
            self.activityIndicator.stopAnimating()
            self.activityIndicator.removeFromSuperview()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

并在UIViewController的子类中:

class MyViewController: ActivityIndicatorPresenter {
    var activityIndicator: UIActivityIndicator { get {return self.spinner}}
    var spinner = UIActivityIndicator()
}
Run Code Online (Sandbox Code Playgroud)

一切正常,但我认为在计算属性的getter中返回存储的属性是一种解决方法。是更漂亮的实现方式吗?

swift swift-protocols

5
推荐指数
0
解决办法
565
查看次数

如何使用Swift中的协议公开Objective-C对象的私有类方法?

考虑两种私有方法UIColor:

  1. styleString返回颜色的RGB字符串的实例方法
  2. _systemDestructiveTintColor返回破坏性按钮使用的红色的类方法.

UIColor.h私有头文件供参考

例如方法,我可以创建一个@objc协议并用于unsafeBitCast公开私有方法:

@objc protocol  UIColorPrivate {
    func styleString() -> UIColor
}

let white = UIColor.whiteColor()
let whitePrivate = unsafeBitCast(white, UIColorPrivate.self)
whitePrivate.styleString() // rgb(255,255,255)
Run Code Online (Sandbox Code Playgroud)

但是,我不确定这对于类方法是如何工作的.

第一次尝试:

@objc protocol UIColorPrivate {
    class func _systemDestructiveTintColor() -> String // Error: Class methods are only allowed within classes
}
Run Code Online (Sandbox Code Playgroud)

有道理,我会把它改成static:

@objc protocol UIColorPrivate {
    static func _systemDestructiveTintColor() -> String
}

let colorClass = UIColor.self
let privateClass = unsafeBitCast(colorClass, UIColorPrivate.self) // EXC_BAD_ACCESS
Run Code Online (Sandbox Code Playgroud)

这会导致崩溃.好吧,这无处可去.我可以使用桥接头,只是将类方法公开为 …

objective-c uicolor ios swift swift-protocols

5
推荐指数
1
解决办法
2779
查看次数

快速协议扩展中的计算变量

刚开始在面向协议的协议编程之后迅速工作,我面临着使用计算变量的问题。

我已经制定了一个协议来检查整个应用程序上的Internet可达性(而不是使用已经实现的UIVIewController子类来实现此行为)。但是,当我运行应用程序时,计算变量()的访问集属性崩溃: 在此处输入图片说明

这是代码:

import UIKit

protocol ReachabilityProtocol: class {
    var reachability: NetReach? { get set }

    func startReachability()
    func stopReachability()

    func internetIsAccessible()
    func internetIsNotAccessible()
}


extension ReachabilityProtocol where Self: UIViewController {

    var reachability: NetReach? {
        get { return reachability }
        set { reachability = newValue }
    }

    func startReachability() {

        do {
            reachability = try NetReach.reachabilityForInternetConnection()
        } catch {
            print("Unable to create Reachability")
            return
        }

        NSNotificationCenter.defaultCenter().addObserverForName(ReachabilityChangedNotification, object: reachability, queue: nil, usingBlock: { notification in

        let reachable = notification.object as! NetReach …
Run Code Online (Sandbox Code Playgroud)

xcode ios afnetworking swift swift-protocols

5
推荐指数
0
解决办法
2707
查看次数

Swift 3,扩展阵列,其中Array的项目属于某种类型

我写了一个包含基本资产数据的结构:

struct Asset: AssetProtocol {

    init (id: Int = 0, url: String) {
        self.id = id
        self.url = URL(string: url)
    }

    var id: Int 
    var url: URL?

}
Run Code Online (Sandbox Code Playgroud)

它订阅 AssetProtocol

protocol AssetProtocol {
    var id: Int { get }
    var url: URL? { get }
}
Run Code Online (Sandbox Code Playgroud)

我希望扩展Array(Sequence),其中该Array中的元素是订阅AssetProtocol的项目.此外,这些函数能够在适当的位置改变数组.

extension Sequence where Iterator.Element: AssetProtocol {

    mutating func appendUpdateExclusive(element newAsset: Asset) {    
        ...
Run Code Online (Sandbox Code Playgroud)

我怎样才能迭代并改变这个序列?我已经尝试了六种方法,似乎无法做到正确!

arrays sequence swift swift-protocols swift3

5
推荐指数
1
解决办法
4303
查看次数

如何使泛型类符合特定类型的协议?

假设存在一个通用结构:

public struct Matrix<T> where T: FloatingPoint, T: ExpressibleByFloatLiteral {
// some methods...
}
Run Code Online (Sandbox Code Playgroud)

是否可以扩展struct以符合约束T使用where子句的协议?比如像

extension Matrix where T: SpecificClass : SomeProtocol {
    // This does not compile :(
}
Run Code Online (Sandbox Code Playgroud)

generics generic-programming swift swift-protocols swift4

5
推荐指数
1
解决办法
1795
查看次数

创建一个通用的UViewController初始化程序

我正在尝试创建UIViewController可用于初始化新实例的扩展。对于项目中的每个视图控制器,我都有一个相应的情节提要。

EditSomethingViewController.swift
EditSomethingViewController.storyboard
Run Code Online (Sandbox Code Playgroud)

这是我到目前为止的内容:

extension UIViewController {

    static func initalize() -> UIViewController? {
        let name = String(self)

        let storyboard = UIStoryboard(name: name, bundle: nil)

        return storyboard.instantiateInitialViewController()
    }

}
Run Code Online (Sandbox Code Playgroud)

但是,这意味着当我使用它时,我仍然必须强制转换响应。

if let viewController = EditSomethingViewController.initalize() as? EditSomethingViewController {
     // do something with view controller here  
}
Run Code Online (Sandbox Code Playgroud)

是否可以通过这种方式创建扩展名,这意味着我不必强制响应?

ps在一个用Swift 2.3编写的旧项目上工作,将不胜感激所支持的答案。

generics uiviewcontroller ios swift swift-protocols

5
推荐指数
1
解决办法
526
查看次数

比较忽略关联值的Swift Enum类型 - 通用实现

我的项目中有几个不同的枚举,符合相同的协议.compareEnumType协议中的方法比较忽略关联值的枚举案例.这是我在游乐场的代码:

protocol EquatableEnumType {
    static func compareEnumType(lhs: Self, rhs: Self) -> Bool
}

enum MyEnum: EquatableEnumType {
    case A(Int)
    case B

    static func compareEnumType(lhs: MyEnum, rhs: MyEnum) -> Bool {
        switch (lhs, rhs) {
        case (.A, .A): return true
        case (.B, .B): return true
        default: return false
        }
    }
}

enum MyEnum2: EquatableEnumType {
    case X(String)
    case Y

    static func compareEnumType(lhs: MyEnum2, rhs: MyEnum2) -> Bool {
        switch (lhs, rhs) {
        case (.X, .X): return true
        case (.Y, …
Run Code Online (Sandbox Code Playgroud)

enums swift swift-protocols

5
推荐指数
1
解决办法
480
查看次数

使用添加默认参数的方法扩展协议

我习惯使用扩展在协议内部使用默认参数,因为协议声明本身不能使用它们,如下所示:

protocol Controller {
   func fetch(forPredicate predicate: NSPredicate?)
}

extension Controller {
   func fetch(forPredicate predicate: NSPredicate? = nil) {
      return fetch(forPredicate: nil)
   }
}
Run Code Online (Sandbox Code Playgroud)

为我工作完美.

现在我有下一个情况,我有一个特定类型的控制器的特定协议:

protocol SomeSpecificDatabaseControllerProtocol {
    //...
    func count(forPredicate predicate: NSPredicate?) -> Int
}
Run Code Online (Sandbox Code Playgroud)

和协议扩展以及控制器的默认方法的实现:

protocol DatabaseControllerProtocol {
    associatedtype Entity: NSManagedObject
    func defaultFetchRequest() -> NSFetchRequest<Entity>
    var context: NSManagedObjectContext { get }
}

extension DatabaseControllerProtocol {
    func save() {
        ...
    }

    func get() -> [Entity] {
        ...
    }

    func count(forPredicate predicate: NSPredicate?) -> Int {
        ...
    }

    //..... …
Run Code Online (Sandbox Code Playgroud)

swift swift-extensions swift-protocols

5
推荐指数
1
解决办法
395
查看次数