Custom class clusters in Swift
I don't believe that this pattern can be directly supported in Swift, because initialisers do not return a value as they do in Objective C - so you do not get an opportunity to return an alternate object instance.
You can use a type method as an object factory - a fairly contrived example is -
class Vehicle
{
var wheels: Int? {
get {
return nil
}
}
class func vehicleFactory(wheels:Int) -> Vehicle
{
var retVal:Vehicle
if (wheels == 4) {
retVal=Car()
}
else if (wheels == 18) {
retVal=Truck()
}
else {
retVal=Vehicle()
}
return retVal
}
}
class Car:Vehicle
{
override var wheels: Int {
get {
return 4
}
}
}
class Truck:Vehicle
{
override var wheels: Int {
get {
return 18
}
}
}
main.swift
let c=Vehicle.vehicleFactory(4) // c is a Car
println(c.wheels) // outputs 4
let t=Vehicle.vehicleFactory(18) // t is a truck
println(t.wheels) // outputs 18
Proper subclassing of class clusters
You've reached the classic double-inheritance problem. You want to be either a RedUIView
or GreenUIView
and be either a MyUIViewiOS6
or a MyUIViewiOS7
view.
Since objective-c does not support double-inheritance, you'll have to decide the difference between what you are, and how you act. Anything that determines what you are, you put in the class. Anything that determines how you act goes into a @protocol
which then can be implemented.
I would subclass MyUIView
since MyUIViewiOS6
and MyUIViewiOS7
correspond to who you are, and then implement a Red
or Green
protocol for certain functionality:
@interface MyRedUIView : MyUIView<RedProtocol> @end
You can check to see if this class conforms to a specific protocol:
if ([class conformsToProtocol:@protocol(RedProtocol)]) {
self.color = [UIColor redColor];
}
If both of them really are who you are, then you have to use four separate classes.
Here's an example using categories. Assuming that you have MyUIView as specified in the question:
GreenView.h
#import "MyUIView.h"
#import "Green.h"
@interface MyUIView (GreenUIView) <Green>
-(BOOL) isGreen;
@end
@interface GreenView : MyUIView @end
GreenView.m
#import "GreenView.h"
@implementation MyUIView (GreenUIView)
-(BOOL) isGreen{
return [self conformsToProtocol:@protocol(Green)];
}
@end
@implementation GreenView @end
Green.h
@protocol Green <NSObject> @end
AppDelegate.m
#import "GreenView.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
GreenView* view = [[GreenView alloc] init];
NSLog(@"%@", [view isGreen]?@"yes":@"no");
return YES;
}
@end
How can i parse a custom marker icon with clustering in iOS Swift
Solution found:Here starts the class in GMUDefaultClusterRenderer.m at clustering folder
- (GMSMarker *)markerWithPosition:(CLLocationCoordinate2D)position
from:(CLLocationCoordinate2D)from
userData:(id)userData
clusterIcon:(UIImage *)clusterIcon
animated:(BOOL)animated {.....
......
I replace the original with this:
if (clusterIcon != nil) {
marker.icon = clusterIcon;
marker.groundAnchor = CGPointMake(0.5, 0.5);
}else{
marker.icon = [UIImage imageNamed:@"K_Annotation.png"];
}
Can I create a class that subclasses from Array?
You can add methods to Array via an extension. Something like:
extension Array
{
func randomObject() -> Element { return self[ Int( arc4random_uniform( UInt32( self.count ) ) ) ] }
}
Now you can do myArray.randomObject()
where myArray is of type Array
Edit: Also, @Addison correctly pointed out that struct types cannot be subclassed in Swift.
Objective-C and Class Cluster pattern
Basically, the instance you have allocated could be thrown away and replaced with a different instance. Technically, this isn't specific to class clusters and that is why when you call super
in any init
method you need to set the result as self
:
self = [super init];
Is it possible to customize cluster image in iOS 11?
You should check to see if the annotation is of type MKClusterAnnotation
. If it is you can then use the memberAnnotations
property to access the member annotations. In your case, for example, you could say:
override var annotation: MKAnnotation?
{
willSet
{
if let cluster = newValue as? MKClusterAnnotation {
image = UIImage(named: "Cluster")
} else {
// set image for non cluster
}
}
}
For more information see WWDC 2017 What's New with MapKit.
Inherit from class with private initializer?
There are various ways to solve this issue:
Declare the initializer as
internal
, that will give you module access and your subclass will be able to call it.Declare the classes in the same file, then
private
won't be an issue anymore (private
enables access from the same file).Instead of abstract classes, you can make
MapItem
aprotocol
andClusterItem
andCluster
could inherit fromGMSMarker
directly. However, this solution may not be good depending on your exact needs.
Make initializer for superclass return a specific subclass?
It's playing fast and loose with inheritance having the parent class know about its subclasses (very poor anti-pattern!) but this would work...
class Measurement {
var unitString : String
class func factory(unknownUnit: String) -> Measurement {
if unknownUnit == "kg" {
return Mass(myUnit: unknownUnit)
} else { // Random default, or make func return Measurement? to trap
return Volume(myUnit: unknownUnit)
}
}
init(myUnit: String) {
// checks if the unit is either Volume or Mass, and returns an instance of that class
self.unitString = myUnit
}
}
class Volume : Measurement {
}
class Mass : Measurement {
}
let mass = Mass(myUnit: "kg") // class: Mass
let volume = Volume(myUnit: "ml") // class: Volume
let shouldntBeVolume = Measurement(myUnit: "ml") // class: Measurement
let shouldntBeMass = Measurement(myUnit: "kg") // class: Measurement
let isVolume = Measurement.factory("ml") // class: Volume
let shouldBeMass = Measurement.factory("kg") // class: Mass
Related Topics
How to Remove Special Characters from String in Swift 2
@Property/@Synthesize Equivalent in Swift
Skspritenode - Create a Round Corner Node
How Come I Can Cast to Nsmanagedobject But Not to My Entity's Type
How to Tap on a Specific Point Using Xcode Uitests
Fbsdkloginmanager Loginwithpublishpermissions Always Returns Iscancelled=Yes
Destinationviewcontroller Segue and Uinavigationcontroller Swift
Found an Unexpected MACh-O Header Code: 1918975009 in Xcode 6
How to Get Directions in Mkmapview Using a Built in Apple API
Dynamically Increase Height of Uilabel & Tableview Cell
Uiwebview and Safari Comparison
Storing Uicolor Object in Core Data
Custom Cordova Plugin: Add Framework to "Embedded Binaries"
Where Do I Find iOS Obj-C Code to Scan and Connect to Wifi (Private API)
App Getting Crash When Click on Googlesignin Button
"No Such Module 'Alamofire'" Xcode Won't Recognize Alamofire Framework
How to Calculate Actual Font Point Size in iOS 7 (Not the Bounding Rectangle)
Code Signing Error: Application Failed Codesign Verification