标签: swift-protocols

UIViewController的默认自定义转换

我正在开发一个库,我想在两个视图控制器之间提供默认的自定义转换,用户也可以提供自己的实现,我想到的第一个想法是覆盖UIViewController和实现UIViewControllerTransitioningDelegate,然后用户可以继承我的CustomTransitionViewController是它最好的方法吗?任何限制?是否有一种更优雅的方式只使用协议,例如默认实现?

import UIKit

class CustomTransitionViewController: UIViewController, UIViewControllerTransitioningDelegate {

  required init?(coder aDecoder: NSCoder) {
      super.init(coder: aDecoder)
      self.transitioningDelegate = self
  }

  override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil:Bundle?)   {
      super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
      self.transitioningDelegate = self
  }

  func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
      return FadeInAnimator(transitionDuration: 0.5, startingAlpha: 0.8)
  }

  func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
      return FadeInAnimator(transitionDuration: 0.5, startingAlpha: 0.8)
  }
}
Run Code Online (Sandbox Code Playgroud)

uiviewcontroller ios swift swift-protocols

7
推荐指数
2
解决办法
605
查看次数

Swift 4.1 中对类绑定协议的弱引用的通用数组

我正在尝试创建一个WeakReference可以放入数组的泛型类型(并最终创建一个泛型弱数组类型)。

到目前为止一切顺利,但以下代码:

class WeakReference<ElementType: AnyObject> {
    weak var element: ElementType?

    init(_ element: ElementType) {
        self.element = element
    }
}

protocol Element: AnyObject {}

class WeakElementHolder {
    var weakElements: [WeakReference<Element>] = []
}
Run Code Online (Sandbox Code Playgroud)

产生这个编译器错误:

WeakReference.swift:12:21: error: 'WeakReference' requires that 'Element' be a class type
    var weakElements: [WeakReference<Element>] = []
                       ^
WeakReference.swift:1:7: note: requirement specified as 'ElementType' : 'AnyObject' [with ElementType = Element]
class WeakReference<ElementType: AnyObject> {
  ^
Run Code Online (Sandbox Code Playgroud)

这很奇怪,因为协议肯定需要一个类 ( AnyObject)。

奇怪的是,如果我省略泛型,一切正常:

protocol Element: AnyObject {}

class WeakElementReference { …
Run Code Online (Sandbox Code Playgroud)

arrays generics weak-references swift swift-protocols

7
推荐指数
1
解决办法
1526
查看次数

为什么“ViewModifier”协议有“关联类型”和“类型别名”?

据我所知,ViewModifier协议的定义如下:

protocol ViewModifier {

    // content view type passed to body()
    typealias Content

    // type of view returned by body()
    associatedtype Body : View

    // only requirement
   func body(content: Self.Content) -> Self.Body

}
Run Code Online (Sandbox Code Playgroud)

我的问题是:

为什么Self.Contenta typealiaswhileSelf.Body是an associatedtype?有什么不同?

type-alias associated-types swift-protocols swiftui

7
推荐指数
2
解决办法
1586
查看次数

无法声明具有内部要求的公共协议扩展

我正在编写媒体播放器应用程序,并创建了自己的框架来管理所有播放器功能.在这个框架中,我有一个名为的公共协议PlayerControllerType和一个内部协议_PlayerControllerType.在PlayerControllerType我已经声明了所有方法和属性,这些方法和属性应该可以从框架外部访问.在_PlayerControllerType我已经定义了几个属性,这些属性由PlayerControllerType框架内部实现的具体类型使用.其中一种类型是PlayerController.其声明如下:

public class PlayerController<Item: Equatable>: NSObject, PlayerControllerType, 
_PlayerControllerType, QueueDelegate
Run Code Online (Sandbox Code Playgroud)

现在我想为我的框架中的类提供一些默认实现,它们符合PlayerControllerType和内部_PlayerControllerType,例如:

import Foundation  
import MediaPlayer  

public extension PlayerControllerType where Self: _PlayerControllerType, Item == MPMediaItem, Self.QueueT == Queue<Item>, Self: QueueDelegate {  

    public func setQueue(query query: MPMediaQuery) {  
        queue.items = query.items ?? []  
    }  

}  
Run Code Online (Sandbox Code Playgroud)

这在Xcode 7 Beta 4中按预期工作.昨天我更新到Beta 6并得到了这个错误:"Extensions不能公开,因为它的泛型要求使用内部类型"(也见截图). Xcode中的错误

我发现这个错误很刺激.当然,这延长了我的框架的好处以外没有任何类型,因为它不能访问内部协议_PlayerControllerType,但它是我的框架内的类型的同时实现是非常有用的PlayerControllerType_PlayerControllerType.

这只是Swift编译器中的一个错误,还是预期的行为?非常不幸的是,这不再适用了,因为现在我必须将这些方法放入一个新创建的基类中,用于所有的PlayerControllers.

任何帮助或反馈将非常感谢.

编辑:以下是协议及其扩展的缩写示例:

public protocol PlayerControllerType {
    typealias Item …
Run Code Online (Sandbox Code Playgroud)

xcode ios swift swift-extensions swift-protocols

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

扩展UICollectionViewDataSource协议以添加默认实现

我有一个相当大的应用程序,它有很多集合视图.大多数集合视图都具有相同的数据源和流布局代表(相同的大小,边距等)的实现.我正在尝试创建一个提供UICollectionViewDataSource和UICollectionViewDelegateFlowLayout的默认实现的协议.这是我的代码.

protocol TiledCollectionView{}

extension UICollectionViewDataSource where Self: TiledCollectionView{
    //default implementation of the 3 methods to load the data ...
}
extension UICollectionViewDelegateFlowLayout where Self: TiledCollectionView {
    //default implementation for layout methods to set default margins etc...
}

class MyViewController: UIViewController, TiledCollectionView, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout{
    // the rest of the required logic for view controller
    // here I Don't implement any CollectionView methods since I have provided the default implementation already
}
Run Code Online (Sandbox Code Playgroud)

问题是,编译器抱怨MyViewController不符合UICollectionViewDataSource.这不应该是这种情况,因为我清楚地说,如果类型是TiledCollectionView,则添加默认实现.

有人可以帮忙吗?

uicollectionview swift swift-extensions swift-protocols protocol-extension

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

'X' 类型的值没有成员 'y' - 协议中的可选函数

我试图更好地理解 Swift 中的协议。特别是可选的协议方法。我认为这个问题可能与我在不同文件中定义/使用的协议有关,但是如果您将以下内容放在操场上,您会遇到同样的问题:

import Foundation

@objc protocol MyProtocol {
    optional func shouldJump() -> Bool
}

extension NSObject : MyProtocol {}

class Test {
    func testJump() {
        let object = NSObject()
        let jump = object.shouldJump?() ?? true

        print("should jump: \(jump)")
    }
}

let t = Test()
t.testJump()
Run Code Online (Sandbox Code Playgroud)

这是错误消息:

error: value of type 'NSObject' has no member 'shouldJump'
            let jump = object.shouldJump?() ?? true
                       ^~~~~~ ~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)

出于某种原因,它不接受已在 NSObject 上定义的协议。代码完成找到它,但编译器不让它通过。

我不确定我的?? true部分是否会起作用,但我希望它是默认值,以防未定义该方法。

我如何让这个工作?

swift swift-protocols

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

使用协议扩展的默认关联类型

我有一个带有associatedType. 我想typealias在协议扩展中为该类型提供一个默认值。这仅适用于从特定类继承的类。

protocol Foo: class {
  associatedtype Bar
  func fooFunction(bar: Bar)
}
Run Code Online (Sandbox Code Playgroud)

协议扩展:

extension Foo where Self: SomeClass {
  typealias Bar = Int
  func fooFunction(bar: Int) {
    // Implementation
  }
}
Run Code Online (Sandbox Code Playgroud)

编译器抱怨'Bar' is ambiguous for type lookup in this context. 我也无法在 swift 书中找到任何有用的东西。

swift swift-protocols protocol-extension

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

有没有办法在触发视觉框架请求(VNDetectTextRectanglesRequest)后取消它?

我正在为 iOS 应用程序运行 Vision Framework 请求,如下所示:

let textDetectionRequest = VNDetectTextRectanglesRequest(completionHandler: self.findTextBoxes)
let textDetectionHandler = VNImageRequestHandler(cgImage: image, orientation: orientation, options: [:])
DispatchQueue.global(qos: .background).async {
   do {
        try textDetectionHandler.perform([textDetectionRequest])
   } catch {
        print(error)
   }
}
Run Code Online (Sandbox Code Playgroud)

它工作正常,我正在使用通知/观察者模式在请求完成后采取进一步的操作。有时,在应用程序中,我需要在请求完成其操作之前取消进程,那么我可以使用 Vision Framework 中的任何类型的协议/委托方法来调用取消吗?

谢谢。

computer-vision ios swift-protocols swift4

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

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
查看次数

Make a swift protocol conform to Hashable

I'm going around in circles trying to get Hashable to work with multiple struct that conform to the same protocol.

I have a protocol SomeLocation declared like this:

protocol SomeLocation {
    var name:String { get }
    var coordinates:Coordinate { get }
}
Run Code Online (Sandbox Code Playgroud)

Then I create multiple objects that contain similar data like this:

struct ShopLocation: SomeLocation, Decodable {
    var name: String
    var coordinates: Coordinate

    init(from decoder: Decoder) throws {
        ...
    }
}

struct CarLocation: SomeLocation, Decodable {
    var name: …
Run Code Online (Sandbox Code Playgroud)

protocols ios hashable swift swift-protocols

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