Faking visibility of system status for camera input

How do you communicate to users that an App is doing something “passive,” like waiting for input from a camera? Sometimes you have to fake it!

Visibility of system status is one of Jakob Nielsen’s 10 Usability Heuristics for User Interface Design, and is stated as:

The system should always keep users informed about what is going on, through appropriate feedback within reasonable time.

Often we’re worried about meeting this guideline for operations that “block” interaction with an App – waiting on data to load, on a process to complete, etc.  However, there are also cases where the App is waiting on some user input, and it’s also important to clearly inform users that the system is still “working” in these cases.

On a recent iOS project we implemented a barcode scanning feature. Technically, this was pretty simple (the iOS AV Foundation Framework does the majority of the heavy lifting with AVMetadataMachineReadableCodeObject). However, some users were confused when launching the scanner because the App simply presented a camera capture view and waited for input. Holding the device over a barcode would capture the barcode and dismiss the camera capture view, but some users questioned “is this working?” until they had gone through the process of scanning a barcode.

To improve the feel of this interaction, we added a visible indication that the camera is running. This involved “faking” some lens movement – the continuous focus setting on an iPhone is so quick that you seldom notice the camera focus, so to emulate this we zoomed in/out a bit and forced a re-focus. The effect looks like this:

Barcode Scanner iOS

 

Although this doesn’t technically do anything for performing a scan, the added effect reinforces that the camera is running and improves the feel of the interaction. The relevant code looks like this:

class ScannerViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
 
    ...
 
    let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
    
    func zoomInOut() {
    do {
            try device.lockForConfiguration()
            device.focusMode = .AutoFocus
            let initZoom: CGFloat = 1.0
            let maxZoom: CGFloat = min(1.1,device.activeFormat.videoMaxZoomFactor - 0.0002)
            for var i: CGFloat = initZoom; i < maxZoom; i = i + 0.0002 {
                device.videoZoomFactor = i
            }
            device.focusMode = .AutoFocus
            for var i: CGFloat = maxZoom - 0.0002; i > initZoom; i = i - 0.0002 {
                device.videoZoomFactor = i
            }
            device.focusMode = .AutoFocus
            device.focusMode = .ContinuousAutoFocus
            device.unlockForConfiguration()
        } catch let error as NSError {
            print(error.localizedDescription)
        }
    }
    ...

}

Leave a Reply

Your email address will not be published.

top