:  ~ 5 min read

Delightful animations

We all love animations. On one hand, they help our eyes be guided, but they also bring a nice finishing touch, a bit of extra care, a bit of emotion; we also prefer a lively UI to a static one, a UI that gives us feedback, that interacts back with us. But, as with anything, too much will be harmful, so let’s explore a few finishing touches that can be added to an app without overwhelming it.

Changing a button’s frame and/or color on touchDown

We usually put a button’s action on touchUpInside and the reason for that is to give the user a chance to change his mind. But the physical action perfor […]

Continue reading →

:  ~ 1 min read

Learning through mini habits

If you’d like to learn a new programming language, try to aim for ”write a line of code” every day. You might rightfully ask ”how will one line help in the long run?” and the answer is rather simple: you will almost never stop at one line of code; it also keeps you connected and the process ongoing.

This is how I learned Ruby a few years ago, by aiming for ”a couple of lines of code”. From there, I ended up creating a ”real” blog with Sinatra (was using some WYSIWYG editor until then). This, in turn, led to me using my blog as a playground for every technology I wanted to learn ever since: Nod […]

Continue reading →

:  ~ 7 min read

CAAnimations and groups

Everyone loves animations and I think every app should make use of them; with care, but that in a future post. The easiest way to add animations is with UIView’s animate method, or with UIViewPropertyAnimators. Pretty straightforward and easy to use, but they don’t support animating CALayer properties, like borderColor or borderWidth. For these, we have CABasicAnimation, or rather all of its concrete subclasses: CABasicAnimation, CAKeyframeAnimation, CAAnimationGroup, or CATransition. In this post we’ll quickly cover CABasicAnimation and CAAnimationGroup.

Say we want to animate the borderColor […]

Continue reading →

:  ~ 1 min read

Easier UIFont usage

In a previous post I was writing about improving working with UIFont and now I’d like to take it one step further in regards with having a quick and easy way to set fonts, if you use a single typeface (font family):

extension UIFont {

   static func regular(_ size: CGFloat) -> UIFont {
      return .systemFont(ofSize: size, weight: .regular) // Or any other font.
   }
	
   static func medium(_ size: CGFloat) -> UIFont {
      return .systemFont(ofSize: size, weight: .medium)
   }

}

This might not seem much, or maybe I’m just lazy, but I find it easier to write and read

let nameLabel = UILabel […]
Continue reading →

:  ~ 1 min read

My Travel Stories

The other week we released My Travel Stories, an app to journal your travels, share beautiful photos with the world, but also find inspiration from others.

There are many apps you could use to journal your travels, be it diary apps, or the stock Photos app; but none of them are a true, focused, travelling journal app. My Travel Stories is a dedicated app, where you can add photos and descriptions for each; nothing more, nothing less.

There are also many review sites and many platforms to share you photos/opinions on, but none of them has true human-to-human interactions. At least that’s how I […]

Continue reading →

:  ~ 12 min read

Avoiding the keyboard on UITextField focus

A couple of posts ago I was writing about handling the Next button automatically. In this post I’d like to write about avoiding the keyboard automatically, in a manner that provides both a good user experience and a good developer experience.

Most apps have some sort of form that requires to be filled, even if just a login/register, if not several. As a user, having the keyboard cover the text field I'm about to fill makes me sad; it's a poor user experience. As developers, we'd like to solve this as easily as possible and have the solution as reusable as possible.

What does a good user experi […]

Continue reading →

:  ~ 2 min read

Optionals, flatMap and you

Say we have a UILabel where we want to display a birthdate with a full format, and an API from where we get a String? with iso8601 format. One of the ways to do this would be:

let dateFromAPI: String?

// [...]

let dateFormatter = DateFormatter.shared // 1
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"

if let dateString = dateFromAPI, // 2
   let date = dateFormatter.date(from: dateString) { // 3
   dateFormatter.dateFormat = nil
   dateFormatter.dateStyle = .full

   dateLabel.text = dateFormatter.string(from: date) // 4
}

DateFormatters are expensive to create, so we either cre […]

Continue reading →

:  ~ 1 min read

Goalee

Yesterday we released Goalee, an app that helps you not lose sight of your life’s goals. The main idea behind the app is that all the annoyances, conflicts or so-called problems we face in our everyday lives pale in comparison with our true goals in life.

The issue I faced, as many others, is that I tend to lose track of what I desire most, exactly because of problems here and there. One approach is to start writing down your goals on a sheet of paper, which I did and it worked; for a while, because I eventually started overlooking said sheet of paper.

I then tried using to-do apps, or habit t […]

Continue reading →

:  ~ 15 min read

Handling the Next button automatically

Entering text in multiple text fields is such a common pattern — everywhere, not just iOS — there should be a way to easily navigate from on field to the next, preferably the ”correct” one. Sadly, iOS doesn’t offer this feature, but let’s see how we could accomplish this ourselves.

First, a quick recap on what we need:

Continue reading →

:  ~ 4 min read

Increasing the tap area of a UIButton

The other day, Soroush wrote a great post about hitTest(_:with:) (you should check it out), which reminded me of a problem I solved the other week: I wanted to increase a UIButton’s tap area, without increasing the button’s frame.

The following code would go in one of the button’s superviews; for example, you might have a mainContainer, which has a UIStackView that contains the button — we’d implement it in mainContainer:

override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
   let biggerButtonFrame = theButton.frame.insetBy(dx: -30, dy: -30) // 1

   if biggerButtonFrame.c […]
Continue reading →