I am trying to implement the CVCalendar cocoapod (https://github.com/Mozharovsky/CVCalendar) and in the instructions it says:
'CVCalendar requires an implementation of two protocols CVCalendarViewDelegate and CVCalendarMenuViewDelegate, please implement both.'
I dont understand how to go about doing this.
You just need to make your class a subclass of CVCalendarViewDelegate and CVCalendarMenuViewDelegate.
class ViewController: UIViewController, CVCalendarViewDelegate, CVCalendarMenuViewDelegate {
Documentation: https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Inheritance.html#//apple_ref/doc/uid/TP40014097-CH17-ID195
Take a look at the answer to this question: Conform to protocol in ViewController, in Swift
As per Oliver's answer you need to add protocols to your class declaration :
class ViewController: UIViewController,CVCalendarMenuViewDelegate,CVCalendarViewDelegate {
You also need to add these two functions to comply with the new protocols:
func presentationMode() -> CalendarMode{
return .monthView
}
func firstWeekday() -> Weekday{
return .monday
}
Related
I have a UIViewController only protocol
protocol VCProtocol where Self: UIViewController {}
I have a function with VCProtocol parameter. Inside the function I can not access any property of UIViewController
func testFunction(vcProtocol: VCProtocol) {
// vcProtocol.view ‼️ error: Value of type 'VCProtocol' has no member 'view'
}
Though I can cast the protocol parameter to UIViewController and then access the property like this:
func testFunction(vcProtocol: VCProtocol) {
(vcProtocol as! UIViewController).view
}
Is this is the way? Do we have any better way?
You can use the & operator to combine protocols
protocol VCProtocol where Self: UIViewController {}
func testFunction(vcProtocol: VCProtocol & UIViewController) {
let view = vcProtocol.view
}
It seems like this is now supported properly from Swift 5. You can try it Xcode 10.2 beta 4. For older versions, you would have to resort to #Ricky Mo's solution.
protocol VCProtocol: UIViewController {
func testFunction(vcProtocol: VCProtocol)
}
class A: UIViewController, VCProtocol {
func testFunction(vcProtocol: VCProtocol) {
debugPrint(vcProtocol.view)
}
}
From the notes,
Protocols can now constrain their conforming types to those that
subclass a given class. Two equivalent forms are supported:
protocol MyView: UIView { /*...*/ }
protocol MyView where Self: UIView { /*...*/ }
Swift 4.2 accepted the second form, but it wasn’t fully implemented
and could sometimes crash at compile time or runtime. (SR-5581)
(38077232)
This question already has answers here:
Redundant conformance of TableView to protocol UITableViewDataSource with Xib Files
(2 answers)
Closed 3 years ago.
I got this error and I don't know how to solve it. Anyone can help me? Basically I want to create table.
This is my code:
import UIKit
class TableViewController: UITableViewController, UITableViewDelegate,
UITableViewDataSource {
I got this error:
Redundant conformance of 'TableViewController' to protocol 'UITableViewDataSource'
Redundant conformance of 'TableViewController' to protocol 'UITableViewDelegate'
I already connect dataSource and delegate in my table view.
Refer to this picture
here
Help me out please :(
UITableViewController already conforms to UITableViewDelegate and UITableViewDataSource so you don't need to specify this again in your class declaration.
Go from
class TableViewController: UITableViewController, UITableViewDelegate, UITableViewDataSource {
// ...
}
to
class TableViewController: UITableViewController {
// ...
}
There are at least 2 conformations in your class. You need to extend only once.
First Posibility:
You conform in the class description AND in the extension. Remove "My Delegate" in the class description.
class MyViewController: MyDelegate{
//class functions here
}
extension MyViewController: MyDelegate{
func1()
}
Second posibility:
You conform in two extensions.
extension MyViewController: MyDelegate{
func1()
}
extension MyViewController: MyDelegate{
func2()
}
Merge them into one extension like:
extension MyViewController: MyDelegate{
func1()
func2()
}
I am trying to add a default implementation to one of my delegate methods. However, after adding the default implementation and removing the method from the class that implements the protocol, I get does not conform to protocol error. It works in a playground.
protocol NavigationDelegate: NSObjectProtocol {
func didSetToolbarVisible(_ isVisible: Bool)
}
extension NavigationDelegate {
func didSetToolbarVisible(_ isVisible: Bool) {
print("Default implementation")
}
}
class MyViewController: NavigationDelegate {
// 'does not conform to protocol' error
}
What am I missing?
A class does not conform to NSObjectProtocol by default, that causes the error.
Change
protocol NavigationDelegate: NSObjectProtocol
to
protocol NavigationDelegate: class
Your NavigationDelegate uses a base protocol of NSObjectProtocol. This means that anything that conforms to NavigationDelegate must also conform to NSObjectProtocol. Change your class declaration to the following:
class MyViewController: NSObject, NavigationDelegate.
Solved it! My NavigationDelegate and its extension were in a different target than the one that MyViewController belongs to. Simply moving the extension to the same target worked.
Hope this helps someone in the future 🤞
In Xcode 8 I'm trying to make a subclass of UICollectionViewController and UICollectionViewLayout but I get the error:
Multiple inheritance from classes 'UICollectionViewController' and 'UICollectionViewLayout'
but they have different parents classes. I'm trying to follow http://nshint.io/blog/2015/07/16/uicollectionviews-now-have-easy-reordering/ tutorial for reorder custom size cells
class WordCollectionViewController: UICollectionViewController, UICollectionViewLayout {
// ...
override func invalidationContext(forInteractivelyMovingItems targetIndexPaths: [IndexPath], withTargetPosition targetPosition: CGPoint, previousIndexPaths: [IndexPath], previousPosition: CGPoint) -> UICollectionViewLayoutInvalidationContext {
var context = super.invalidationContext(forInteractivelyMovingItems: targetIndexPaths, withTargetPosition: targetPosition, previousIndexPaths: previousIndexPaths, previousPosition: previousPosition)
return context
}
}
Beyond my comment. Swift DOES NOT support multiple inheritances. UICollectionViewLayout is a class, so since your WorldCollectionViewController is already inheriting from UICollectionViewController you cannot inherit from UICollectionViewLayout (you also don't want to). This:
class ViewController: UIViewController, UITextFieldDelegate {
}
is not multiple inheritances but a single inheritance from the UIViewController and conformance to a protocol UITextFieldDelegate.
You can read more about what protocols are and how to use them here: https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html
Essentially protocols are like a set of guidelines. These guidelines specify methods and properties. If a class conforms to a protocol then it must implement the methods and properties described in the protocol's guidelines. For example:
protocol hasAVariablePotato {
var potato: String! { get set }
}
Any object that conforms to this protocol must have a variable (not a let constant) potato that is of type String and implicitly unwrapped. Like so:
class PotatoFarmer: Farmer, hasAVariablePotato {
}
The above PotatoFarmer class inherits from a Farmer class and but does not conform to hasAVariablePotato because there is no potato var! So the above will generate the error:
Type 'PotatoFarmer' does not conform to protocol 'hasAVariablePotato'
To fix this error the programmer must add in the properties and methods of the protocol, like so:
class PotatoFarmer: Farmer, hasAVariablePotato {
var potato: String!
}
The error will now disappear because you have conformed to the protocol.
For your situation you want to make separate subclasses of UICollectionViewLayout and UICollectionViewLayoutAttributes. To see how to do this check here (a great FREE tutorial on the subject):
https://www.raywenderlich.com/107439/uicollectionview-custom-layout-tutorial-pinterest
Swift doesn't support multiple inheritances. UICollectionViewController and UICollectionViewLayout both are class. Don't inherit both the class. You can use below code instead
import Foundation
import UIKit
class Test:UICollectionViewLayout{
override func invalidationContext(forInteractivelyMovingItems targetIndexPaths: [IndexPath], withTargetPosition targetPosition: CGPoint, previousIndexPaths: [IndexPath], previousPosition: CGPoint) -> UICollectionViewLayoutInvalidationContext {
var context = super.invalidationContext(forInteractivelyMovingItems: targetIndexPaths, withTargetPosition: targetPosition, previousIndexPaths: previousIndexPaths, previousPosition: previousPosition)
return context
}
}
I have a Swift class that inherits from UIViewController, and I was wondering if there was any way that I could use the same class on a UITableViewController to avoid repetition.
class GradientViewController: UIViewController {
// My class
}
Are there any ways to use this class on a UITableViewController, like so?
class MyTableViewController: GradientViewController {
// My table view controller
}
Thanks in advance
Swift only supports single inheritance.
You could use a protocol to avoid repetition.
protocol YourProtocolName {
// Protocol stuff
}
class GradientViewController: UIViewController, YourProtocolName {
// Implement protocol requirements
}
class MyTableViewController: UITableViewController, YourProtocolName {
// Implement protocol requirements
}
If it makes sense, you could even use a protocol extension to provide default implementations such that conforming types don't need to add any code to conform.