Why I can not inherit from multiple classes in swift just like it's library classes
Swift does not support multiple inheritance, following Objective C in this. This is NOT inheritance from two classes:
class SecondViewController: UIViewController, UITextFieldDelegate
It is inheritance from one class UIViewController
and adopting the UITextFieldDelegate
protocol. Read about protocols at https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html
How to do multi-inheritance in swift?
As stated in the comments by @Paulw11 is correct. Here is an example that involves A & B inheriting from C. Which I have named DogViewController
and CatViewController
(which inherits form PetViewController
). You can see how a protocol might be useful. This is just an ultra basic example.
protocol Motion {
func move()
}
extension Motion where Self: PetViewController {
func move() {
//Open mouth
}
}
class PetViewController: UIViewController, Motion{
var isLoud: Bool?
func speak(){
//Open Mouth
}
}
class DogViewController:PetViewController {
func bark() {
self.speak()
//Make Bark Sound
}
}
class CatViewController: PetViewController {
func meow() {
self.speak()
//Make Meow Sound
}
}
//....
let cat = CatViewController()
cat.move()
cat.isLoud = false
cat.meow()
multiple inheritance from classes
In swift your class can inherit just from single class.
You can have a look on protocol and protocol oriented programming.
The other solution is:
// Class A inherits from UIViewController
class A: UIViewController
// Class B inherits from A and also from UIViewController
class B: A
In your example you said that your main class inherits from BaseViewController
which inherits from UIViewController
so if you want to create another class which inherits from BaseViewController
and UIViewController
you just need to do:
class A: BaseViewController
that's make it inherit from UIViewController
too.
How to derive one class from two different classes in Swift based on API level?
Unfortunately (or fortunately depending on how you look at it), exactly what you're trying to do is not possible with Swift or Objective-C from a language perspective. The @available
attribute you're using is to tell the compiler that this class is only available if you're compiling a target with a deployment target greater than what you specified.
@MartinR made mention of the #available and the general pattern that you should employ to achieve your goal.
The reason these 2 things are available and necessary to support backward compatibility is because compiled code doesn't necessarily have all of the information about the runtime. The compiler/linker check for the existence of APIs, classes, etc by using the headers and module maps of the SDK at compile time. But, your app is linked with the system frameworks dynamically at runtime. This pattern is why your app doesn't have to be distributed with copies of every part of the SDK that it uses.
In your case, you have SDK9 and are trying to support a runtime of iOS 8 or less. The SwipeTableViewCell
doesn't work in iOS 8 likely because it uses APIs that are only available in iOS 9. All of this doesn't prevent SwipeTableViewCell
from existing on iOS 8 devices, it just prevents it from working.
You really should evaluate whether you need to support iOS 8 at all. If you change your target's deployment target to iOS 9 and release it to the App Store, people running iOS 8 won't get the update or be able to install it.
Update
After doing some thinking, and some research, I came up with a possible solution for your situation. I only tested it in an environment that relies on a storyboard for the UI, but I think it can gracefully bridge your iOS targets.
import UIKit
class ViewController: UITableViewController {
@IBOutlet var staticCell: Any? // In the storyboard, tell the cell to by a "MySwipeableCell"
override func viewDidLoad() {
super.viewDidLoad()
if staticCell is SwipeTableViewCell {
print("This class was converted magically, which means we're on iOS 9 or later")
}
}
}
class SwipeTableViewCell: UITableViewCell {
// Standin for your library class
}
class MySwipeableCell: UITableViewCell {
override func awakeAfter(using aDecoder: NSCoder) -> Any? {
if #available(iOS 9, *) {
// This will replace the MySwipeableCell with an instance of SwipeTableViewCell instead
return SwipeTableViewCell.init(coder: aDecoder)
}
return self
}
}
Inheriting Multiple Classes in F#
UICollectionViewDelegate
and UICollectionViewDataSource
are not class
es, but protocol
s, which are like interface
s in F#
So your could should look something like this (abstract code):
[<Register ("LandlordHome")>]
type LandlordHome (handle:IntPtr) =
inherit UIViewController (handle)
interface UICollectionViewDelegate with
// implementation of UICollectionViewDelegate
interface UICollectionViewDataSource with
// implementation of UICollectionViewDataSource
Cannot inherit from non-open class swift
Found the answer myself.
In Swift 3 you can now mark a class as open
instead of public
this allows files outside of the module to subclass that class.
Simply replace public
in your module class with open
.
Reference here.
Related Topics
Unowned Vs. Weak. Why We Should Prefer Unowned
Pass Variables from One Viewcontroller to Another in Swift
In Swift, How to Convert a String to an Enum
Finish Asynchronous Task in Firebase With Swift
Swift: How to Detect Linear Type Barcodes
Println Dictionary Has "Optional"
Adding 3D Object to Argeoanchor
Take a Snapshot of Current Screen with Metal in Swift
Accessing Appstate in Appdelegate with Swiftui's New iOS 14 Life Cycle
Identify Face of a Cube Hit on Touches Began in Swift - Scenekit
Compile Error in Swift 4 on Parameter Passing
Iboutlet and Ibaction in Swift
What's the Difference Between Struct Based and Class Based Singletons
Using Combine's Future to Replicate Async Await in Swift