我正在开发一个库,我想在两个视图控制器之间提供默认的自定义转换,用户也可以提供自己的实现,我想到的第一个想法是覆盖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) 我正在尝试创建一个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) 据我所知,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?有什么不同?
我正在编写媒体播放器应用程序,并创建了自己的框架来管理所有播放器功能.在这个框架中,我有一个名为的公共协议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不能公开,因为它的泛型要求使用内部类型"(也见截图).

我发现这个错误很刺激.当然,这延长了我的框架的好处以外没有任何类型,因为它不能访问内部协议_PlayerControllerType,但它是我的框架内的类型的同时实现是非常有用的PlayerControllerType和_PlayerControllerType.
这只是Swift编译器中的一个错误,还是预期的行为?非常不幸的是,这不再适用了,因为现在我必须将这些方法放入一个新创建的基类中,用于所有的PlayerControllers.
任何帮助或反馈将非常感谢.
凯
编辑:以下是协议及其扩展的缩写示例:
public protocol PlayerControllerType {
typealias Item …Run Code Online (Sandbox Code Playgroud) 我有一个相当大的应用程序,它有很多集合视图.大多数集合视图都具有相同的数据源和流布局代表(相同的大小,边距等)的实现.我正在尝试创建一个提供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
我试图更好地理解 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部分是否会起作用,但我希望它是默认值,以防未定义该方法。
我如何让这个工作?
我有一个带有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 书中找到任何有用的东西。
我正在为 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 中的任何类型的协议/委托方法来调用取消吗?
谢谢。
我的好奇心促使我将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协议。 …
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) swift-protocols ×10
swift ×7
ios ×5
swiftui ×2
arrays ×1
generics ×1
hashable ×1
protocols ×1
struct ×1
swift4 ×1
type-alias ×1
viewbuilder ×1
xcode ×1