Use UIViewController class on UITableViewController - ios

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.

Related

Redundant conformance of 'TableViewController' to protocol 'UITableViewDataSource' [duplicate]

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()
}

How do you create a base class with a weak delegate that conforms to a generic protocol?

I want to create a base class for UIViews that require that a delegate conform to a specific protocol defined by the View.
class BaseView<P>: UIView {
weak var delegate: P?
}
protocol MyProtocol {}
class MyView: BaseView<MyProtocol> {}
This gives me the error: "'weak' must not be applied to non-class-bound 'T'; consider adding a protocol conformance that has a class bound".
How do I fix this error? Or is there some work around? Or is it not so necessary to make the delegate variable weak in the first place? Thanks in advance.
Since weak is a property assigned to anything that is of class type and not struct, you have to explicitly constraint your generic parameter to be of class type and you do that this way:
class BaseView<P: AnyObject>: UIView {
weak var delegate: P?
}
#objc protocol MyProtocol {
}
class MyView: BaseView<MyProtocol> {
}
Only one need of clarification. Usually to make a protocol be of class type usally you would make it conform to class this way:
protocol MyProtocol: class { }
However, for some reason the compiler throws an error if you were to do it that way. I learned that this is a bug that could be learned about more here:
How to require that a protocol can only be adopted by a specific class
So adding the #objc helps silence the warning and error both.
You should add type constraint to your generic by adding MyProtocol and create a class that conforms MyProtocol.
You can find more info here.
Updated code:
class BaseView<P: MyProtocol>: UIView {
weak var delegate: MyProtocol?
}
protocol MyProtocol: class {}
class MyProtocolImp: MyProtocol {
}
class MyView: BaseView<MyProtocolImp> {
}
But I don't know why you use P parameter in class.
You can write without this:
class BaseView: UIView {
weak var delegate: MyProtocol?
}
protocol MyProtocol: class {}
class MyView: BaseView {
}

Default protocol implementation causes 'does not conform to protocol' error

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 🤞

Swift: How to implement CVCalendar

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
}

Delegate declared in UIView subclass won't work in UIViewController?

I'm trying to create a reusable UIView that I can place in multiple UIViewControllers. I gave it delegate methods that I want the parent UIViewControllers to access, but it throws me an error (commented in the code below). What's a better way I can solve this?
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var cameraView: CameraView!
override func viewDidLoad() {
super.viewDidLoad()
self.cameraView.delegate = self
//ERROR: Cannot assign a value of type 'viewController' to a value of type 'CameraViewDelegate?'
}
}
protocol CameraViewDelegate {
func cameraViewShutterButtonTapped()
func cameraViewimagePickerTapped(imageData: NSData)
}
class CameraView: UIView {
var delegate:CameraViewDelegate?
//Ect...
}
You have not specified that ViewController conforms to the CameraViewDelegate protocol. You should amend your code to this:
class ViewController: UIViewController, CameraViewDelegate {
…at which point Xcode will complain that you have not implemented cameraViewShutterButtonTapped() and cameraViewimagePickerTapped(), which at least tells you that you're on the right track!
Side note: do you really want the camera view to have a strong reference to its delegate? You might want that to be weak.
You need to have your ViewController class implement the CameraViewDelegate protocol, like so:
class ViewController : UIViewController, CameraViewDelegate { ... }

Resources