iOS, Titanium

Titanium Live Blur, well kind of…

Since the release of iOS7, the Live Blur effect has been extremely popular.  Since Apple doesn’t yet provide this effect natively the community has come up with a few different approaches to achieve this effect.

Toolbar Layer

One common approach to achieving a live blur is to use a layer from the UIToolbar.  This allows you to use the same live blur effect that a IUToolbar has, but with the same functionality of a UIView.  This approach is reliable with good performance.  The downside, is you have no control over the Blur and in iOS 7.1 the blur was made softer making it difficult to see when used in come color schemes. Adrian  Opaladini has created an excellent Titanium module called Live BlurView which implements this approach. If you are looking at implementing a light live blur I highly recommend checking out this module.

Timer Driven

The next approach to implementing a live blur effect is to use a timer and a blur algorithm or library such as GPUImage.  Typically this is implemented using a timer which at a specific duration takes a snapshot of the source view and applies a blur effect.  As you can imagine the downside to this approach is you need to implement the refresh code yourself.   This usually requires managing the processes of a timer, view snapshot, and image processing.  Not a ton of code, but you don’t get anything out of the box. The upside, is complete control over the process.  This allows you to use the blur effect that looks best in your app, at a frequency that makes sense. There is an example of how to do this using the Ti.BlurView module here.

Another Option…

I really wasn’t happy with either the Toolbar or Timer approaches.  I wanted more control then I had with the Toolbar approach, but the idea of firing a timer when it wasn’t needed wasn’t appealing, especially considering the performance impact.  This got me thinking, that for many Titanium apps, the UI fires all types of events when the application state has changed.  Why not hook into these events. Out of this came the Scroll Blur example for the Ti.BlurView module.

See it in action

ScrollBlur

The Code

var mod = require('bencoding.blur');
	
exports.createWindow = function(){	

	var win = Ti.UI.createWindow({
		backgroundColor:'blue',
		barColor:"#999", title:"Blur on Scroll"
	});

	function createRows() {
	
	    function buildRow(el) {
	        var row = Ti.UI.createTableViewRow({
	            width:150, height:120
	        });
	
	        var headerImage = Ti.UI.createImageView({
	            image: el.image, 
	            width:Ti.UI.FILL, height:Ti.UI.FILL
	        });
	
	        var titleLabel = Ti.UI.createLabel({
	            text: el.title,
	            width: Ti.UI.FILL, height: '30dp', 
	            color:'green',
	            horizontalWrap: false, bottom: '5dp', 
	            left: '5dp', right: '5dp',
	            font: {
	                fontSize: '20dp', fontWeight:'bold'
	            }
	        });
	
	        row.add(headerImage);
	        row.add(titleLabel);
	        return row;
	    };
	
	    var rows=[];
	    for (var iLoop=0;iLoop<100;iLoop++){
	        rows.push(buildRow({ title: 'Test Row '+iLoop, 
	        					image: 'cat.jpg'}));
	    }
	    return rows;
	};

	var list = Ti.UI.createTableView({
	    width:Ti.UI.FILL,  height:Ti.UI.FILL, data:createRows()
	});
	win.add(list);

	var imgView = mod.createGPUBlurImageView({
		height:250, width:Ti.UI.FILL, zIndex:500,top:0,
		blur:{
			type:mod.IOS_BLUR, radiusInPixels:1
		}		
	});
	win.add(imgView);	

	var w = Ti.Platform.displayCaps.platformWidth;
	var blur = {
		timerId: null,
		apply : function(){
			Ti.API.debug("Taking screenshot");
			var screenshot = list.toImage();
			Ti.API.debug("applyBlur : Cropping screenshot");
			screenshot.imageAsCropped({x:0,y:0, height:250,
										width:w});
			Ti.API.debug("set screenshot as image to ImageView");
			imgView.image = screenshot;
			Ti.API.debug("set blur so we will update");
			imgView.blur={
				type:mod.BOX_BLUR, radiusInPixels:5
			};	
			Ti.API.debug(" Done with Blur");				
		}		
	};
		
	list.addEventListener('scroll',function(f){
		Ti.API.debug("action fired : scroll");
		
		if(blur.timerId!=null){
			Ti.API.debug("Timer already set, returning");
			return;
		}
		
		blur.timerId = setTimeout(function(){
			blur.apply();
			blur.timerId = null;	
		},50);	
			
	});

	list.addEventListener('scrollend',function(f){
		Ti.API.debug("action fired : scrollend");
		
		if(blur.timerId!=null){
			Ti.API.debug("Clearing Interval");
			clearInterval(blur.timerId);
			blur.timerId = null;
		}
		blur.apply();	
	});
 	 		
	win.addEventListener('open',function(f){
		blur.apply();
	});

	win.addEventListener('close',function(f){
		if(blur.timerId!=null){
			clearInterval(blur.timerId);
		}	
	});
		
	return win;
};
iOS, Titanium

Blur Effects with GPUBlurImageView

Looking for a high performance way to apply Blur effects?  The latest release of the Ti.Blur module provides the new high performance GPUBlurImageView component.  GPUBlurImageView is an extended version of the Ti.UI.ImageView with one extra  property, blur.  Through this single property you can apply iOS, Box, or Gaussian blur effects.

Initial tests show a 50% performance improvement over the prior Ti.BlurView blur functionality.  If you have a retina display on your mac you will find the GPUBlurImageView renders faster on device then in the simulator due to the number of pixels being rendered.

iOS Blur Code Example:


var mod = require('bencoding.blur');

var imageView = mod.createGPUBlurImageView({
    height:Ti.UI.FILL, width:Ti.UI.FILL,
    image:"42553_m.jpg",
    blur:{
        type:mod.IOS_BLUR, radiusInPixels:1
    }
});

See the BlurView in action:

ios_demo

iOS, Titanium

iOS 7 Screen Brightness

Looking to implement a day and night mode to your app?  Ti.Brightness provides a series of APIs that allows you to read the iOS 7 screen brightness and be notified if it changes.

Getting the screen brightness

Reading the iOS 7 screen brightness level is easy.  Just call the getScreenBrightness method as shown below.  This method provides Titanium access to the underlying iOS [UIScreen mainScreen].brightness platform API.

var brightness = require('ti.brightness');
var level= brightness.getScreenBrightness();
Ti.API.info("Brightness Level:" + level);

* If you are running this in the simulator, 0.5 will always be returned.

Brightness Changed Event

You can use the changed event as shown in the following snippet to trigger an event after the user has adjusted their screen brightness. This event provides Titanium access to the name UIScreenBrightnessDidChangeNotification notification.

function onBrightChange(e){
    Ti.API.info(JSON.stringify(e));
    alert("Your Screen brightness is level: " + e.brightness);
};

brightness.addEventListener('changed',onBrightChange);

* This event will not trigger in the simulator

In Action

The following movie shows the module in action and how Ti.Brightness can be used to add a dark and light theme to your app.

Titanium

Digital Assistant Built with Titanium Mobile

Ever want to build your own version of Siri that understands keywords specific to your app or business domain?  This can be done easily using Titanium and a few modules.  The below video is a proof of concept I put together to demonstrate some of what can be done.  Over the next couple of posts I’ll walk through the components used to create this example.

Ti Digital Assistant Video

Modules used:

iOS, Titanium

Text to Speech with Titanium

iOS 7 introduced the speech synthesizer API AVSpeechSynthesizer.  With this API you can have iOS speak a phrase in the language of the text provided.  Used correctly this can add a compelling level of user interaction and direction to your app.

The Utterance iOS Titanium module provides a simple to use API for interacting with AVSpeechSynthesizer in the simulator or on device.

In just a few lines of code you can speak a phrase in any supported language.  Here is an example in Japanese.

First we require the module into our Titanium program


var utterance = require('bencoding.utterance');

Then we create a new Speech object

var speech = utterance.createSpeech();

Finally we call the startSpeaking method and provide the text we wish to have read.

    speech.startSpeaking({
        text:"こんにちは"
    }); 

For a full list of the methods available please visit the project n github here.

Here the module in action

The following is a video showing the module in action.

How to get the module:

Titanium

TableView Header Zoom

Want to create a TableView Header Zoom effect like Foursquare, Tapbots, and others?  You can do this in Titanium with only a couple lines of code.

The following code snippet shows how to expand a Ti.UI.ImageView in a Ti.UI.TableView HeaderView to achieve a zoom like effect when the user over scrolls the TableView as demonstrated in the preview below.

TableViewHeader

'use strict';

var win = Ti.UI.createWindow({
    backgroundColor: 'white',
});

//Generate some sample rows
var rows = [];
for (var iLoop=0;iLoop<100;iLoop++){
    rows.push({ title: 'demo row #'+iLoop});
}

//Create our TableView, nothing special
var tableView = Ti.UI.createTableView({
    width:Ti.UI.FILL, height:Ti.UI.FILL,
    data:rows
});

//Create a ImageView for the TableView HeaderView
var imgView = Ti.UI.createImageView({
	width:Ti.UI.FILL, height:150,
	image:"cat.png"
});
//Set our ImageView as the headerView
tableView.headerView = imgView;

win.add(tableView);

//Need to capture a few session variables 
//The most important one is to grab the original height
// of the TableView HeaderView
var _scollTimer = null, 
	_origionHeight = tableView.headerView.height;

//Most of what we need happens in the scroll event
tableView.addEventListener('scroll',function(e){	

	//Clear our timer each time
	if(_scollTimer!==null){
		clearInterval(_scollTimer);
	}

	//If the user has scrolled past the header, 
        //reset the origional height
	if(e.contentOffset.y>_origionHeight){
		if(tableView.headerView.height !== _origionHeight){
			tableView.headerView.height = _origionHeight;
		}		
	}else{
		//Calculate our zoom or expand height
		var zoomOffSet = ((e.contentOffset.y<0)?-1:1);
		var zoomHeight = (tableView.headerView.height + 
					((zoomOffSet*-1)*
                          ((zoomOffSet*e.contentOffset.y)/3)));
		zoomHeight= ((zoomHeight > _origionHeight) 
                            ? zoomHeight : _origionHeight);
		if(tableView.headerView.height !==zoomHeight){
			tableView.headerView.height =zoomHeight;
		}			
	} 

	//Timer is needed since scrollend doesn't always fire
	//so just in case we set a timer to set the origional height
	if(e.contentOffset.y===0){
        _scollTimer = setTimeout(function()
        {
			tableView.headerView.height = _origionHeight;
        },250);		 
	}		
});

//If the user end scrolls something other then the 
//HeaderView check if we need to reset
tableView.addEventListener('scrollend',function(e){	
	if(_scollTimer!=null){
		clearInterval(_scollTimer);
	}	
	if(tableView.headerView.height !== _origionHeight){
		tableView.headerView.height = _origionHeight;
	}	
});

win.open();

Get this snippet on gist here.

iOS, Titanium

Creating Blurred Backgrounds & Overlays in Titanium

With iOS 7 and the new flat design aesthetic many apps are using a blurred background or overlay to help set depth or attention.  The Ti.BlurView iOS native module now makes this easy to implement in Titanium.  Since we are using CoreImage you can use this in iOS 6 or greater.

Below shows Ti.BlurView example app.js in action, for a full walk through see the video here.

BlurView Demo
The Ti.BlurView module’s source is available on Github here.

You can get started today using Ti.BlurView with the following:

Please note you need iOS 6 or greater to use this module so make sure to set the min-ios-ver in your Titanium tiapp.xml to at least the value displayed below.

<min-ios-ver>6.0</min-ios-ver>

Below is a snippet showing how to create a blurred background image similar to the Yahoo Weather app.

var mod = require('bencoding.blur');

var win = Ti.UI.createWindow({
	backgroundColor:'blue'
});

var bgView = Ti.UI.createView({
	height:Ti.UI.FILL, width:Ti.UI.FILL,
	backgroundImage:"42553_m.jpg"
});
win.add(bgView);

var blurView = mod.createView({
	height:Ti.UI.FILL,
	width:Ti.UI.FILL,
	blurLevel:5, blurCroppedToRect:false,
        backgroundView:bgView
});
bgView.add(blurView);

win.addEventListener('open',function(d){

	var container = Ti.UI.createView({
		backgroundColor:"#fff", borderRadius:20,
		top:100, height:150, left:40, right:40
	});
	blurView.add(container);
	var label = Ti.UI.createLabel({
		text:"Show how to blur like the yahoo weather app.",
		color:"#000", width:Ti.UI.FILL,
		height:50, textAlign:"center"
	});
	container.add(label);

});

win.open();

You can also use the applyBlurTo method to create your own Blur View containers.  For information on how to do this please see the documentation here.

Android, iOS, Titanium

Ti.mely Native Timer Modules for Titanium

The Ti.mely project provides Titanium access to iOS and Android native timers.  The native nature of these timers can be advantageous for background or long interval poling.

Using Ti.mely

The usage is straightforward, you simply create a new timer object

var timer = timerMod.createTimer();

Attach a listener to listen for the onIntervalChange event as shown below

    function showUpdate(d){
        var msg = "interval changed - interval set to " + d.interval;
            msg += " interval count = " + d.intervalCount;
        Ti.API.info(msg);
    }

    timer.addEventListener('onIntervalChange',showUpdate);

Initialize the timer by calling the start method.  This method takes the interval in milliseconds and an optional debug flag which will print timer information to your console window.

    timer.start({
        interval:2000,
        debug:true
    });

To stop the timer, simply call the stop method as shown below.

timer.stop();

Native Consideration, ie Side Effects

Each time an interval elapses the onIntervalChange event will be fired.  The firing of this event will cause a trip over the Kroll JavaScript bridge.  For this reason using Ti.mely to implement high speed timers of 500 milliseconds or less could negatively impact app performance.

Get the module

The Ti.mely source code and compiled modules are available on Github(https://github.com/benbahrenburg/ti.mely) under the MIT license.

You can download the compiled modules using the following links

Example app.js

The below sample demonstrates how to use the Ti.mely module.  This app.js is include within the module’s example folder or available for iOS here and Android here.

var timer =  require('ti.mely').createTimer();

var win = Ti.UI.createWindow({
	backgroundColor:'#fff'
});

var how2Label = Ti.UI.createLabel({
	text:"Enter Duration in milliseconds",
	top:20, left:7, right:7, height:20,color:"#000"
});
win.add(how2Label);

var durationText = Ti.UI.createTextField({
	value:1000, top:50, left:7, right:7, height:40, color:"#000"
});
win.add(durationText);

var counterLabel = Ti.UI.createLabel({
	top:100, width:Ti.UI.FILL, height:40,left:7, right:7,color:"#000"
});
win.add(counterLabel);

function showUpdate(d){
	var msg = "interval changed - interval set to " + d.interval;
            msg += " interval count = " + d.intervalCount;
	Ti.API.info(msg);
	counterLabel.text = "Updated " + d.intervalCount  + " times.";
};

var startButton = Ti.UI.createButton({
	title:"Start", top:200, left:7, height:40, width:125
});
win.add(startButton);

startButton.addEventListener('click',function(e){
	counterLabel.text ="Starting Timer";
	timer.addEventListener('onIntervalChange',showUpdate);
	timer.start({
		interval:durationText.value,
		debug:true
	});
});

var stopButton = Ti.UI.createButton({
	title:"Stop", top:200,
	right:7, height:40, width:125
});
win.add(stopButton);

stopButton.addEventListener('click',function(e){
	timer.stop();
	timer.removeEventListener('onIntervalChange',showUpdate);
	counterLabel.text ="Press the Start button to test again";
});

win.open();

iOS, Titanium

iOS7 Style Switches in Titanium

Included in the iOS7 redesign is a compelling update to the look of the UISwitch.  The SevenSwitch project by Ben Vogelzang provides the iOS7 design as a drop in replacement for the UISwitch in iOS5+.  I wanted to use this awesome project in my iOS Titanium apps so I created the Ti.SevenSwitch module.

See it in action:

Get the module:

You can download the source at on Github or the compiled module here.

The example:

The demo:

demo

The code:


var mod = require('ti.sevenswitch');

var win = Ti.UI.createWindow({
backgroundColor:'white', layout:'vertical'
});

win.add(Ti.UI.createLabel({
text:"Default", textAlign:"left", height:25, left:7, top:0
}));

var defaultSwitch = mod.createSwitch({
top:5, left:20, value:true, height:30, width:50
});
win.add(defaultSwitch);

win.add(Ti.UI.createLabel({
text:"Sized Switch", textAlign:"left", height:25, left:7, top:15
}));

var bigSwitch = mod.createSwitch({
top:5, height:50, width:250, left:20, value:true
});
win.add(bigSwitch);

win.add(Ti.UI.createLabel({
text:"Knob Color", textAlign:"left", height:25, left:7, top:15
}));
var colorKnobSwitch = mod.createSwitch({
top:5, left:20, height:30, width:50, value:true, knobColor:"orange"
});
win.add(colorKnobSwitch);

win.add(Ti.UI.createLabel({
text:"Active/Pressed Color", textAlign:"left", height:25, left:7, top:15
}));
var activeColorSwitch = mod.createSwitch({
top:5, left:20, height:30, value:true, activeColor:"orange", height:30, width:50
});
win.add(activeColorSwitch);

win.add(Ti.UI.createLabel({
text:"On Color", textAlign:"left", height:25, left:7, top:15
}));
var onColorSwitch = mod.createSwitch({
top:5, left:20, height:30, value:false, onColor:"yellow", height:30, width:50
});
win.add(onColorSwitch);

win.add(Ti.UI.createLabel({
text:"Inactive Color", textAlign:"left", height:25, left:7, top:15
}));
var inactiveColorSwitch = mod.createSwitch({
top:5, left:20, height:30, value:false, inactiveColor:"blue", height:30, width:50
});
win.add(inactiveColorSwitch);

win.open();
Android, iOS, Titanium

Securely: Titanium Security Module

The first release of Securely the Titanium security module is now available on Github.  The goal of this project is to provide the tools and components needed to build secure Titanium apps.  Securely provides a comprehensive set of methods designed to easily handle your most common security requirements.

Features include

  • Secure Properties
  • Key Generators
  • String Encryption
  • File Encryption
  • PDF Protection

Get the module

The source and compiled module are both available on Github under the Apache 2 license.

Learn more

Learn more about this module by visiting the following links on Github:

  •  Documentation : Complete method level documentation with examples
  •  Samples : Example app.js files demonstrating how to use each proxy type