Setting our app apart can be tricky. We don't want to deviate too far from established conventions, but we don't want to blend in to the crowd either. Small amounts of "polish" to an app's UI can go a long way to making it feel special.
Today we'll check out one more tool in our arsenal for doing this. It's a library from Andrea Mazzini called SubtleVolume.
The idea here is to improve upon the default, screen-obscuring, built-in volume overlay. iOS's system interface is fine for most apps, but often it can get in the way of the content the underlying app is presenting.
SubtleVolume solves this by providing an elegant volume view that we can put anywhere on the screen. Let's try it out:
The real world doesn't have straight edges. Things are rounded. Our UIViews can be too! Most of us know about the cornerRadiusproperty on CALayer. We can set a value, then see all the corners round themselves to that value:
contentView.layer.cornerRadius=8
Nice, but what if we only want to round some of the corners though?
For this, we'll need to get a bit more creative. We can use an often-overlooked type called UIRectCorner.
It lets us describe which corners we'd like to round. Then we'll use a UIBezierPath to create a "mask" layer that will only allow some of the content to "show through".
We pass in an option set for the byRoundingCornersparameter, listing out the corners we'd like rounded.
Success! Happy rounding!
Update: Shout-out to Reddit-reader /u/cuomo456 who reminds us to update/replace our layer masks anytime the view/layer we're masking's frame or bounds changes. If we don't, we could find ourselves scratching our heads why our rounded corners aren't working in a UITableViewCell, for example.
Today we'll look at an interesting library from Evan Dekhayser called KBKit. It extends UIKit to add support for navigating around using a physical keyboard. (Think either bluetooth or other keyboard connected to an iPad, but would also work on iPhone.) Let's take a look.
KBKit consists of a few subclasses of common UIKit classes. KBTableView adds Up Arrow, Down Arrow, and Return Key functionality to UITableView. Very cool.
lettableView=KBTableView(frame:CGRect.zero,style:.Plain)tableView.onSelection={(indexPath:NSIndexPath)in// called when user pressed 'Return' or 'Command + D'}tableView.onFocus={(current:NSIndexPath?,previous:NSIndexPath?)in// called as user navigates with arrow keys}
We can use KBNavigationController to gain a Command + Left Arrow shortcut for going "back" (i.e. popping to the previous view controller in the stack).
Last but not least, KBTabBarController adds support for pressing Command + 1, Command + 2, Command + 3, etc. to change the currently selected tab. It supports up to 5 tabs. Neat!
More info about KBKit can be found at git.io/kbkit
One easy trick to make our app look a little nicer is to animate changes to the heights of the UITableViewCells in our UITableView. All we need to do is make whatever changes to our models we want to cause our cells to be a different height. (For example we might let the user tap a button to "expand" all comments in an app). Then we just call:
tableView.beginUpdates()tableView.endUpdates()
UIKit will interpolate & animate the changes, neat!
iOS gives us a ton of great capabilities to build upon. Being able to use the user's current geographic location in our apps really has changed the world.
We always need to ask for the user's permission first though, so we might as well do it in style! Today we'll check out a simple yet beautiful library from Sven Tiigi called STLocationRequest that uses Flyover to provide a great looking "location access prompt" view controller.
We'll begin by importing STLocationRequest, and configuring and showing a location request controller.
Except iOS 😭, which doesn't support them out of the box. Today we'll try a library from Michael Choe called SwiftSVG which provides great support for parsing and rendering SVG files. Let's take a look.
SwiftSVG supports a ton of different ways of getting SVGs into our app.
SwiftSVG also provides a custom UIViewsubclass we can use in Interface Builder that supports IBInspectable/IBDesignable.
More broadly, it's important to think about the reasons why we might want to use SVGs in our app. SVGs are essentially XML files (Open one up in a text editor, you'll see.)
They are instructions on how to draw a set of paths. The files are incredibly small.
It happenstothebest of us. We're going along, composing some UIViews in our app. We're styling them, configuring them, we can't wait to try them out. That's when we see it. A big, empty, unescapable void of nothingness right where our views should be! 😱
Today we'll look at some tips to solve a case of missingUIViews.
First, we should arm ourselves with tools to help inspect what's going on. Xcode's own View Debugger is a great place to start, and Reveal.app is a fantastic third-party solution.
Whether it's one of these tools, or simply writing some in-depth logging functions, our first step should be to look at both our view hierarchy and its layout for anything funky.
We can use private functions like recursiveDescription to print out a handy tree-view of our views to Xcode'sConsole.
Most of these debugging sessions stop here, as the problem often involves a view not being in the correct place in the hierarchy, or Auto Layout has gone and done something wacky with our views' locations.
If we're still stuck though, here are some sanity checks we can perform:
Are any viewshidden?
How about transparent? (0 alpha)
Is it masked via a maskLayer?
Does it have a CGRectZeroframe?
Is the key UIWindow a weird size or in a weird place?
Try making each view a specificuglycolor (the static .XColor() functions on UIColor work wonders here).
Is another view covering it up?
Is .clipsToBounds enabled and a strange frame/bounds is causing the view to be clipped?
If all else fails, comment out everything, and add it back one bit at a time until something fails.
Finally, Hue can analyze a UIImage, returning a tuple of colors it finds inside.
let(bg,primary,secondary,_)=albumArt.colors()
It provides background, primary, secondary and detail colors from the image. We can the use these to create interfaces such as the one found in iTunes on OS X, where the colors in the UI match those found in the album artwork. Neat!
Most iOS developers have used the fantastic UIViewanimateWithDuration family of functions. But there's another, slightly-lesser known static function on UIView that can help us transition like a pro. Let's check it out:
The function we'll be trying is transitionWithView. At first glance you'll see it's takes the same duration, options, and closures as its more-popular sister function.
However, instead of applying our changes over time, this function will (conceptually) take a snapshot of our view before and after the work in the animations** closure** is performed, then visually transition from the first snapshot to the second.
The type of transition depends on the animation option we pass in. We can do everything from simple cross-dissolves (fades), to fancy 3D flips. Super handy for simple transitions.
Download a sample project at j.mp/bite193. In it, we flip a thumbs up emoji using this incredibly simple technique.
Low Power Mode debuted in iOS 9. It's a great way to get another hour or two of use out of a device.
When Apple first introduced this functionality, they touted how the feature turns of lots of little things that contribute to the battery savings.
It turns out we can actually provide these same savings in our own apps. Today we'll learn how. Let's get started:
The first way we'll interact with Low Power Mode is through a property on NSProcessInfo.
Here we're working on app that displays animated GIFs. When the user stops scrolling, we automatically begin looping the GIF. However, if the user has Low Power Mode enabled, we'll save a few CPU/GPU cycles by requiring the user to tap to start the animation:
Then, inside lowPowerModeChanged, we can check with NSProcessInfo again. Now when a user returns to our app, we'll start/stop visible GIFs based on the Low Power Mode state. Neat!