Include an Extension for a Class Only If iOS11 Is Available

Include an extension for a class only if iOS11 is available

Xcode 9 beta 4 will build, if @available is added to each method. The build still fails if @available is added only at the extension level.

How do I mark an IBOutlet as available for a specific iOS version

You can set this condition for version specific execution on same view controller.

if #available(iOS 11.0, *) {

let pdfView = PDFView(frame: UIScreen.main.bounds)
let url = Bundle.main.url(forResource: "How", withExtension: "pdf")
pdfView.document = PDFDocument(url: url!)
self.view.addSubview(pdfView)

} else {
// Fallback on earlier versions
}

Supporting older versions of iOS

Move all your delegate conformances to extensions, and then add @available attribute to the extensions. For example:

@available(iOS 11.0, *)
extension DragBoardViewController : UIDragInteractionDelegate { ... }

If you write these conformances as extensions, Xcode 9 will automatically give you fix-its to add the @available attribute.

Remember, you absolutely can have these delegate methods defined in iOS 10; they just won't be called. The point of @available is to prevent other parts of the code from calling this without first wrapping it in an #available check.

A nice way to explore this is to download Apple's sample code and then just set the deployment target to 10.0. You'll see lots of fix-its pop up to help you through the process and show how to do it in your own code.

Xcode 11 backward compatibility: UIWindowScene is only available in iOS 13 or newer

The template in Xcode 11 uses a scene delegate. Scene delegates and the related classes are new in iOS 13; they don't exist in iOS 12 and before, and the launch process is different.

To make a project generated from an Xcode 11 app template backward compatible, you need to mark the entire SceneDelegate class, and any methods in the AppDelegate class that refer to UISceneSession, as @available(iOS 13.0, *).

You also need to declare a window property in the AppDelegate class (if you don't do that, the app will run and launch but the screen will be black):

var window : UIWindow?

The result is that when this app runs in iOS 13, the scene delegate has the window, but when it runs in iOS 12 or before, the app delegate has the window — and your other code may then need to take account of that in order to be backward compatible.

iOS11 How to handle a custom file dropped in a custom view

I admit, it's not straightforward :

  • you can list all the UIDragItems dragged by the user in the UIDropSession items member
  • each of these items have a NSItemProvider itemProvider member
  • this item provider has an optional String? suggestedName member that may not be nil

A simple loop to print all the session's items suggested names :

for item in session.items {
if let name = item.itemProvider.suggestedName {
print(name)
}
}

Practically, when files come from the File app it will provide the name of the file without its extension, but given you can easily access its UTI, you can append an extension that will be close to the original one (jpeg instead of jpg for example).

How to access extension of UIColor in Swift?

You have defined an instance method, which means that you can call
it only on an UIColor instance:

let col = UIColor().getCustomBlueColor()
// or in your case:
btnShare.setTitleColor(UIColor().getCustomBlueColor(), forState: .Normal)

The compiler error "missing argument" occurs because
Instance Methods are Curried Functions in Swift,
so it could equivalently be called as

let col = UIColor.getCustomBlueColor(UIColor())()

(But that would be a strange thing to do, and I have added it only to
explain where the error message comes from.)


But what you really want is a type method (class func)

extension UIColor{
class func getCustomBlueColor() -> UIColor{
return UIColor(red:0.043, green:0.576 ,blue:0.588 , alpha:1.00)
}
}

which is called as

let col = UIColor.getCustomBlueColor()
// or in your case:
btnShare.setTitleColor(UIColor.getCustomBlueColor(), forState: .Normal)

without the need to create an UIColor instance first.



Related Topics



Leave a reply



Submit