BRYXBanner is a great new library by Harlan Haskins for displaying "dropdown" notifications banners. It has a very straightforward API, while remaining extremely flexible. Let's take a look at some different ways to use it.
Momentarily show a banner. By default banners are dismissed on tap, swipe, or after the duration has elapsed.
letbanner=Banner(title:"New Mission Alert",subtitle:"New mission added to the schedule.",image:nil,backgroundColor:UIColor.lightGrayColor())banner.show(duration:3.0)
Without a duration, the show function caused the banner to be shown until the user taps it. Here we're passing in a closure that will be executed when the user taps the banner.
letbanner=Banner(title:"Life Form Detected",subtitle:"An unknown lifeform has been found.",image:UIImage(named:"alien"),backgroundColor:UIColor.redColor()){print("banner tapped!")}banner.hasShadows=falsebanner.show()
Disable image tinting to display all kinds of images.
banner.shouldTintImage=false
Use the provided .textColor property to change all the colors at once, or use the exposed title and detail labels to completely customize the look of each banner, including font face, size, color, etc.
More info about BRYXBanner can be found at git.io/banner
Photo Editing Extensions are a powerful way for apps to integrate with the system Photos app. Users can begin editing a photo, jump into a third-party extension, and return seamlessly back to the system editing interface. Let's try making one.
We begin by adding a new Photo Editing Extension target to our project.
Our extension will use CoreImage (covered in Bite #32) to convert a photo to black and white. The basic workflow goes like this:
User launches our extension while editing inside Photos.app
a PHContentEditingInput object is handed to us via the startContentEditingWithInput... function
User performs the edits they would like using our view controller
User taps Done button (provided by the system)
System asks us for a PHContentEditingOutput object containing our changes to the image via finishContentEditingWithCompletionHandler.
Let's move on to the code.
Along with the input object, we also receive a placeholderImage which we'll use as the initial image in our own image view.
Game Center is a great way to easily add things like leaderboards, multiplayer, challenges, etc. to your iOS or OS X game. Let's try it out by authenticating a user, then reporting a score to a leaderboard.
We start by grabbing the local player, and setting an authentication handler closure. This will be called automatically when it's first set. This will handle showing the login screen if necessary.
importGameKitletleaderboardID="com.magnus.beggarscanyon.womprats"classGameViewController:UIViewController{funcauthenticateWithGameCenter(){// called inside viewDidLoadNSNotificationCenter.defaultCenter().addObserver(self,selector:Selector("authenticationDidChange:"),name:GKPlayerAuthenticationDidChangeNotificationName,object:nil)GKLocalPlayer.localPlayer().authenticateHandler={viewController,erroringuardletvc=viewControllerelse{return}self.presentViewController(vc,animated:true,completion:nil)}}funcauthenticationDidChange(notification:NSNotification){reportScore(1138)// report example score after user logs in}}
After the user is logged in we call our reportScore function, which looks like this:
ResponseDetective is a new debugging library from Adrian Kashivskyy and the team at Netguru for "intercepting" HTTP activity and logging it. You can configure different sets of Interceptor classes, depending on what kinds of data you'd like to see. Let's set it up:
The first thing we'll need to do is register some request and response Interceptors. ResponseDetective comes with quite a few Interceptors out of the box, and you can of course create your own. Here we'll log all the headers of all requests and responses, as well as the content of any JSON requests.
We start with the default session config, and insert the InterceptingProtocol at the front of it's protocol classes.
Finally, we create a session with our config and kick off a new task to an example API endpoint.
Using a UISegmentedControl to switch view controllers is very common, even Apple does it:
Let's build this using UIPageViewController and UISegmentedControl.
We start with a blank storyboard, drag out a UIPageViewController and set it as the initial view controller. Then drag out two UIViewControllers to switch between. We'll select the page view controller and choose Editor > Embed In > Navigation Controller.
Then we drag out a UISegmentedControl and drop it into the title area of the navigation bar of our page view controller. Finally, we create an @IBAction function that will get called when the selected segment changes.
The code is pretty straightforward, note the use of R.swift to grab those two view controllers from our storyboard. (covered in Bite #52).
Dynamic Type is a system introduced back in iOS 7 with the intention of unifying and simplifying how users change their preference for how big text should be on the screen. While the user choice is simple, under the hood Dynamic Type earns its name by dynamically adjusting things such as spacing between characters and character weights to make text as readable as possible.
Letโs take a look at how to add simple Dynamic Type support.
Text Styles
The main way you interact with Dynamic Type is through the built-in set of text styles. As of iOS 9, 9 styles are available to choose from:
UIFontTextStyleTitle1
UIFontTextStyleTitle2
UIFontTextStyleTitle3
UIFontTextStyleHeadline
UIFontTextStyleSubheadline
UIFontTextStyleBody
UIFontTextStyleFootnote
UIFontTextStyleCaption1
UIFontTextStyleCaption2
Retrieving Fonts
If youโre using the system font, all you need is:
Lastly, you'll want to update your UI when the user changes their preferences in Settings.app. Observe this notification and trigger a re-layout when it occurs:
It makes it easy to add drawing and text overlay capabilities to your app. Today we're going to use it to build a view controller that will allow our users to sign their name on the screen using their finger. Let's get started.
We start with the "Single View" template and import jot.
We instantiate a new JotViewController, and add it as a child view controller of our SignatureViewController. We'll do this inside viewDidLoad:
R.swift is a tool by Mathijs Kadijk that takes the resources in your app (images, segues, storyboards, nibs, etc.), examines them and generates a file in the root of your project called R.generated.swift containing a simple struct that maps your resources' actual names to Swift properties. R.swift updates the file each time you build, so you can focus on using your resources instead of managing them.
Why do this? For starters, it gives us Xcode native autocompleteion of resources names (finally). We're also saved from hardcoding strings throughout our app, or needing to go update a set of constants somewhere everytime we add a resource.
Let's look at some examples of where R.swift comes in handy. First up, images:
R.swift also makes it easy to work with our cell reuse identifiers. It even includes extensions for UITableView and UICollectionView that save you from casting your cell's type:
PINRemoteImage is a new and promising solution for asynchronously downloading images. It was created by the team at Pinterest and has been battle tested in their extremely popular iOS app. Let's import PINRemoteImage, take a look at how to use it, and see what it can do:
Images are downloaded and decoded off the main thread. They're then cached using a fast, non-deadlocking parallel object cache. (Courtesy of another Pinterest library, PINCache). Upon subsequent requests the in-memory, then disk caches will be checked before re-downloading.
Processing
You can process the image before caching occurs. Here we'll use Toucan (covered in Bite #40) to convert the image into a circular avatar.
Optionally, you can enable a mode supporting progressive JPEG images. They're treated with a nice blur effect, so they look great even at low resolutions.
imageView.updateWithProgress=true
Animated GIF Support
PINRemoteImage also comes with built-in support for Flipboard's blazing fast animated GIF library, FLAnimatedImage. All you have to do to use it is create an FLAnimatedImageView instead of a UIImageView:
Let's say you have a table view with some cells showing a list of crew members. It'd be great if when the user taps a cell, it would โexpandโ to reveal some actions that can be performed on that crew member. Let's dive in.
Setup View Hierarchy
As you can see, we lean on UIStackView pretty heavily. The constraint shown here is the one we'll be animating.
Animate the Constraint
In our cell's setSelected(animated:) function, we animate the constraint just like we covered back in Bite #9. After the animation's done, we hide/show the toolbar. This triggers the top-level stack view to recalculate it's height.
Our view controller takes care of resizing our cells by updating the 'expanded' state of each crew member when the selection changes and a pair of calls to tableView.beginUpdates/endUpdates inside the tableView:didSelectRowAtIndexPath: and tableView:didDeselectRowAtIndexPath:.
Download the complete working project here: j.mp/bite050