Solution to the iOS software keyboard cover part of the UI

Problem 1

Often in develop iOS app we need to build a form that contain text input (sign up, contact detail, address detail). Sometimes the software keyboards will get in the way and cover part of the UI.

The simple solution is UITableView, UITableView will nicely handle this problem by reduce the table view size or more technical set the content inset to allocate space for keyboard. It also will scroll to the selected text field.

But at times we want to use a lot of custom layout which need to embed UIs in a scroll view or have a text view covers the entire screen.

Solution 1

Use notification center to capture keyboard show and hide event and allocate space accordingly. This is a solved problem, there are tons of solution in stackoverflow.com. The gist of the solution look similar to this:

First Observe keyboard will show and hide notification, and don’t forget to remove notification in dealloc

for keyboardWillShow

The code will be similar for key board will hide method, simply set the insert to all zero

While we added a content inset we also added the same inset to scroll indicator inset or the scroll bar will end above the keyboard.

You can also animate layout constraints or frame change

Problem 2

What if the view is in a Popover or Form sheet?

Solution 2

It turned out that the solution is pretty simple. We need to figure out the view frame in respect to the app window and deduct the bottom space from the keyboard height.

This also works for the iPhone as well as the multi window mode in iPad, since the view frame and the application window frame will have the same maximum y value.

j j j

UIButton adjust image size.

The Problem

I’ve been working with a few buttons that requires an image icon at work lately. Some of the icons are used in different places where the actual image are smaller then the recommended minimum touch area size. So you either get a Larger icon for the button or a smaller button.

Simple Solution

My first work around was to create a new assets for the icon with padding added. This result in multiple images are required to represent the same icon. If an icon need to be replace then multiple assets need to be created and replace in code or interface builder. Not so nice right.

Better Solution

The better way to handle this is to use

i.e.

or in interface builder

Both the code block and interface builder setting will add 10 point margin on all side of the image. So the button touch area can be bigger then the image.

j j j

Xcode auto build number

All you need to do to enable this technique is to add a run script build phase any time after “Copy Bundle Resources”:

Super useful script to auto generate build number. There difference between this and the other techniques is this script does not overwrite info.plist, which require you to make another commit. I set my building number in info.plist to auto and let the script do the job.

j j j

Swift – StringLiteralConvertible

Today I want to have a look at StringLiteralConvertible. The concept for StringLiteralConvertible is to convert a inline string to a object type.

Alternatively, you can give string function extra functionality

To adapt class to StringLiteralConvertible, the class need to conform to the protocol StringLiteralConvertible and convertFromExtendedGraphemeClusterLiteral and have a required initalizer

Now Account class can do something like these

j j j

Autolayout contraint

This week I had an idea to revive my blog. I going to writting a series of articles on let’s write Objective C. This was inspired by Youtube series like “let’s play Simcity”. So let’s get started

So my first article is on auto layout. I played with auto layout before for my work project, but I only used it for Storyboard. So this week I started to explore how to programmably use auto layout.

There are a few issues you need to keep in mind when using auto layout:

  • You can programmably add view using frame, the system will translate it to auto layout
  • Constraints added to views need to be fully realised, UIKit need to know excatly how to render the view
  • For example: (top, left, right bottom) or (top, left, width, height)
  • You MUST turn off translatesAutoresizingMaskIntoConstraints on the view
  • View need to be added to the super view before constraints can be added
  • Positional constraints are added to the parent view


Simple right

j j j

How to restore windows instance from a snapshot in Amazon Web Service

Recently my company suffered a major crash in Amazon Web Service (AWS) after a AWS outage. We have to restore all data from backup, it was a painful experience with many glitches here and there, luckily we were able to recover.

So we re-evaluated the our backup strategy and most simple method was using AWS volume snapshot to take regular backup snapshot of the instance volume. The AWS snapshot feature is very cool. First it creates a complete backup store of your instance, then the subsequent snapshots are all created as incremental thus they are extremely fast. You can also remove any increment snapshots and AWS will manage state of the snapshot automatically in the backend.

We ran into a problem when we try to recreates an instance using the snapshot. For linux instance it’s simple, the AWS console handles everything for you, but for windows instance the process is not as trivial. So here is the steps to recreate an windows instance from AWS snapshot:

First create a volume or volumes from snapshots, make sure they are in the same region zone for the new Windows Instance. Write down the volume id.
create volume from snapshot

Then you need to launch a new windows instance. Make sure to pick the same ami as the original instance from the snapsnot. You can find the ami id in in the AWS console Instance section.
find instance ami and instance id

Once the instance has started and make sure it’s online health check passes then turn it off (do not terminate). Write down the instance id then go to volume section and detach root volume from the instance (use instance id to find the volume).

Find the root volume created from the snapshot, attach it to the instance. When ask for Device id write “/dev/sda1”. Attach all other volumes.
attach root volume

Start the instance and now you have restored your instance from a snapshot

j j j

Spring MVC ajax request with UTF 8 support

Recently for my Dropbox Writer project, I ran into a issue with transferring none English characters between server and client side. There are not a lot of solutions on the web and those solutions are very inconsistent.

Explain my situation

I created a Spring MVC project what can create text files in Dropbox. Dropbox uses UTF 8 for text encoding, thus it supports non English characters. My application uses ajax to drive rest service calls to transfer data between html based client side and spring mvc based server side. I’ve added CharacterEncodingFilter to the web.xml as following:

The problem

When I create a file with name contains Chinese characters, the returned file name is scrambled. The problem is my application uses @ResponseBody in my restful ajax calls to produce json data but those data is not returned in UTF 8 format.

I’ve spent sometime researching and testing a few solutions and I want to share those with you.

Solution 1

Don’t use @ResponseBody. Return void in the controller, and use HtppServletResponse to return string with valid formatting.

Advantage: This will always output text with correct text format, and it’s very simple to understand.

Disadvantage: Very cumbersome. You are going away from the Spring MVC model and writing directly to the HttpServlet model.

Solution 2

Return the an Response Entity object and set it’s content type.

Better then the last solution, but you still feel there is a lot of plumbing involved.

Solution 3

This is it; this is the most elegant solution and it took me a while to figure out.

When I saw this solution, it blown my mind. Yes this is really that simple. There is no plumbing, you tell spring mvc directly how to return formatted text. The downside is you will always need to return UTF 8 text.

j j j