Monday, November 30, 2009

iPhone dev Stupidity 110: Fine Grained Observing for Text Field

1. Using Key-value Observing to get update for a UITextField editing like this:

[nameField_ addObserver: self forKeyPath: @"text" options: NSKeyValueObservingOptionPrior context: nil];

You will only get the observing method (- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context) called when the edit is done - the text field lost focus.

2. To observe each character input, we need NSNotificationCenter (from apple forum):

[[NSNotificationCenter defaultCenter] addObserver: self  selector: @selector(textFieldTextDidChange:) name: @"UITextFieldTextDidChangeNotification"  object: nil];


where to find out the @"UITextFieldDidChangeNotification" string? It's in the UITextField.h:

UIKIT_EXTERN NSString *const UITextFieldTextDidBeginEditingNotification;


UIKIT_EXTERN NSString *const UITextFieldTextDidEndEditingNotification;


UIKIT_EXTERN NSString *const UITextFieldTextDidChangeNotification;


and sure apple had started iPhone SDK in 2005:


//  UITextField.h


//  UIKit


//


//  Copyright 2005-2009 Apple Inc. All rights reserved.


iPhone dev Stupidity 109: NSAttributedString, NSFormatter for UIT

1. from stackoverflow : NSAttributedString is not on iPhone.

2. from iPhone Dev SDK : You can't plug an NSFormatter onto a UITextField - thus you can't provide a partial string when input in text field:
is not available on iPhone. 





Sunday, November 29, 2009

iPhone dev Stupidity 108: Scrolled UITextField

If a text field get focused during scrolling, the scrolling will stop.

So better to focus it when the scroll animation is done: 
 * for program triggered scroll: - (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
 * for finger dragged scroll: - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView 

Saturday, November 28, 2009

iPhone dev Stupidity 107: LuaFileSystem

Some dependency:





To use LuaFileSystem, we need LuaRocks to install the lfs package.

LuaRocks relies on wget to parse the rock specs (not available on Mac OS X).

lfs will build into a lfs.so. If necessary, you need to copy it to 'require' search paths of lua and add the access rights to your user/usergroup.


iPhone dev Stupidity 106: Protocal for Category, Override


iPhone dev Stupidity 105: Confuse alpha = 0.0 with remove

To avoid flicker when removing a view, you might use an UIView animation to set a alpha = 0.0 and remove the view in the animation stop callback.

Make sure to assert(view.retainCount == 1) before removing. For if you have reference count error (retainCount > 1) and the view will not get removed - but you can't see it since the alpha has set to 0.0.

Of course, you can set the alpa = 0.5 in debug mode to "see" if it's removed finally.

Wednesday, November 25, 2009

iPhone dev Stupidity 104: Update Navigation Bar

from apple help doc:

When the user changes the top-level view controller, whether by pushing or popping a view controller or changing the contents of the navigation stack directly, the navigation controller updates the navigation bar accordingly. Specifically, the navigation controller updates the bar button items displayed in each of the three navigation bar positions: left, middle, and right. Bar button items are instances of the UIBarButtonItem class. You can create items with custom content or create standard system items depending on your needs. For more information about how to create bar button items, seeUIBarButtonItem Class Reference.

Check the doc for detailed rules for the left, middle and right view updating.


A UINavigationBar object uses a stack to manage navigation items (instances of UINavigationItem) that represent a state of the navigation bar. You change the navigation bar by pushing navigation items using the pushNavigationItem:animated: method or popping navigation items using thepopNavigationItemAnimated: method. Methods with an animated: argument allow you to animate the changes to the display.


and some error:

2009-11-26 07:45:11.742 Flip[404:20b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Cannot call pushNavigationItem:animated: directly on a UINavigationBar managed by a controller.'


Monday, November 23, 2009

iPhone dev Stupidity 102: Do you have to release IBOutlet?

from stackoverflow:

Your IBOutlets are probably @properties. If they are, and you have retain as an attribute, then you do need to release in -dealloc

A best practice: 

self.myoutlet = nil; in dealloc

This works for both the retained and assigned IBOutlet. The retained will release and the assigned will do nothing.


iPhone dev Stupidity 103: NSZombie and Memory leaks

from here:

NSZombieEnabled creates leaks ON PURPOSE so you can track down calls to objects that are released prematurely. When you run with NSZombieEnabled, objects are never dealloced. When it's time to dealloc the object, NSZombieEnabled tells the runtime to turn the object into an instance of NSZombie. Any attempt to message an NSZombie will result in a runtime exception. Always remember to remove the NSZombieEnabled flag before sending an app into production! Due to the fact that dealloc is overridden, your app will never free any memory - it will just grow and grow. It's for testing and debugging only.


iPhone dev Stupidity 101: How to draw text vertically?

1. Drawing NSString in unusual direction : limited to ascii string and have effect like this:

    use CGContextShowText(ctxt, tbuf.c_str(), tbuf.length()); and CGAffineTransform 

2. CGFontGetGlyphsForUnichars

   to draw unichar we need this function to get glyph out of a unichar. Then core graphic has a set of function for showing glyph like this one:


void CGContextShowGlyphsAtPoint (
CGContextRef c,
CGFloat x,
CGFloat y,
const
CGGlyph glyphs[],
size_t count
);


but CGFontGetGlyphsForUnichars is a private API for iPhone. So we got:

3. A replacement for CGFontGetGlyphsForUnichars

on github

-----

4. bonus: draw gradient filled UILabel.

also uses: extern void CGFontGetGlyphsForUnichars(CGFontRef, const UniChar[], const CGGlyph[], size_t);


iPhone dev Stupidity 100: viewDidUnload

From apple doc:

Called when the controller’s view is released from memory.

- (void)viewDidUnload

Discussion

This method is called as a counterpart to the viewDidLoad method. It is called during low-memory conditions when the view controller needs to release its view and any objects associated with that view to free up memory.


iPhone dev Stupidity 99: Start/End of a scrolling (with drag)

Since UITableView is a subclass of UIScrollView, a scroll begins from:

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView


ends at:

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView


Wednesday, November 11, 2009

iPhone dev Stupidity 98: Bar place holder for view

Set the top and bottom bar for the view, if it meat to be in a navigation controller with toolbar at the bottom:



Thus you can get the right view size without calculating (by sub the bar height - 44).

Monday, November 02, 2009

iPhone dev Stupidity 97: SVN Locked

try: svn cleanup project folder and sub folders

some times you need to feed svn with some fake files which it fails to find.

iPhone dev Stupidity 96: XCode command line

man xcodebuild

iPhone dev Stupidity 95: Non freed memory

If the Object Alloc looks like this, there must be some memory you forget to free but hold a reference.


iPhone dev Stupidity 94: Delete content of scrollview when scroll

If you delete the content view of a UIScrollView in:

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView


later there's still some animation work need to be done by cocoa, and the error will happen (note that ScrollerHeartbeatCallback):



A Hack to solve - delayed remove:

// !!! a hack


// directly remove container from superview, later there's some heart beat callback for smoothing the scrolling


// which will still trying to use the old scroller, and when fails to find, there'll be a BAD ACCESS failure


// here we just delay the remove.


container.alpha = 0.0;


[container performSelector: @selector(removeFromSuperview) withObject: nil afterDelay: 0.1];


iPhone dev Stupidity 93: Nested UIScrollView

UIScrollView can be nested to form kind of 2D scroller - you can scroll the row by row and each row itself holds a horizontal scroll view.

In the scroll delegate you need to respond differently for the inner and outer scroller.