Sunday, October 11, 2009

iPhone dev Stupidity 56: Sqlite3 Lua binding

Lua scripting for Sqlite3

1. using sqlite3 binder: lsqlite3
    fix the make file to link with lua.a - (the default is liblua51 which might be for win/linux)
    make it will produce a lsqlite3.bundle which is not in the lua path

2. fix luaconf.h to add *.bundle in search path(from lua-users.org)

    #define LUA_CPATH_DEFAULT \
     "./?.bundle;"  LUA_CDIR"?.bundle;" LUA_CDIR"loadall.bundle;" \
     "./?.so;"  LUA_CDIR"?.so;" LUA_CDIR"loadall.so"

    Then:
    > make macosx
    > make install

Now you can require 'lsqlite3' to script more.

The test suite of lsqlite3 can pass while there's many non-aligned pointer release error (which doesn't matter very much).



iPhone dev Stupidity 55: SQL in 10 Min

Tips from Sam's Teach Yourself SQL in 10 Minutes:

Lesson 3:
* it is perfectly legal to sort data by a column that is not retrieved.
* If you want to sort descending on multiple columns, be sure each column has its own DESC keyword.

Lesson 4:
* Making the client application (or development language) do the databases job will dramatically impact application performance and will create applications that cannot scale properly. In addition, if data is filtered at the client, the server has to send unneeded data across the network connections, resulting in a waste of network bandwidth usage.
* because AND ranks higher in the order of evaluation, the wrong operators were joined together.
* The biggest advantage of IN is that the IN operator can contain another SELECT statement, enabling you to build highly dynamic WHERE clauses.

Lesson 6:
* The brackets ([]) wildcard is not supported by all DBMSs. - SQLite3 doesn't support it.
* Search patterns that begin with wildcards are the slowest to process.

Lesson 7:
* || is actually the preferred syntax, so more and more DBMSs are implementing support for it. - SQLite3 doesn't support the + syntax.
* an unnamed column cannot be used within a client application because the client has no way to refer to that column. To solve this problem, SQL supports column aliases. An alias is just that, an alternative name for a field or value. Aliases are assigned with the AS keyword.

Lession 8:
* If you do decide to use functions, make sure you comment your code well, so that at a later date you (or another developer) will know exactly what SQL implementation you were writing to* SQLite3 core functions at: http://www.sqlite.org/lang_corefunc.html

Lesson 9:
* Use COUNT(column) to count the number of rows that have values in a specific column, ignoring NULLvalues.* When specifying alias names to contain the results of an aggregate function, try to not use the name of an actual column in the table. Although there is nothing actually illegal about doing so, many SQL implementations do not support this and will generate obscure error messages if you do so.

Lesson 10:
* Every column listed in GROUP BY must be a retrieved column or a valid expression (but not an aggregate function).
* The difference between HAVING and WHERE Here's another way to look it:WHERE filters before data is grouped, and HAVING filters after data is grouped. This is an important distinction; rows that are eliminated by a WHERE clause will not be included in the group. This could change the calculated values which in turn could affect which groups are filtered based on the use of those values in the HAVING clause.
* you should make that distinction yourself. Use HAVING only in conjunction withGROUP BY clauses. Use WHERE for standard row-level filtering.

Lesson 11:
* Breaking up the queries over multiple lines and indenting the lines appropriately as shown here can greatly simplify working with subqueries.
* Subquery SELECT statements can only retrieve a single column. Attempting to retrieve multiple columns will return an error.

Lesson 13:
* It is also worth noting that table aliases are only used during query execution. Unlike column aliases, table aliases are never returned to the client.
* Self joins are often used to replace statements using subqueries that retrieve data from the same table as the outer statement. Although the end result is the same, many DBMSs process joins far more quickly than they do subqueries. It is usually worth experimenting with both to determine which performs better.

Lesson 14:
* The UNION automatically removes any duplicate rows from the query result set (in other words, it behaves just as do multiple WHERE clause conditions in a single SELECT would).

Lesson 15:
* Always Use a Columns List As a rule, never use INSERT without explicitly specifying the column list. This will greatly increase the probability that your SQL will continue to function in the event that table changes occur.

Lesson 16:
* Before you use a WHERE clause with an UPDATE or a DELETE, first test it with a SELECT to make sure it is filtering the right records—it is far too easy to write incorrect WHERE clauses.
Lesson 18:
* Performance Issues Because views contain no data, any retrieval needed to execute a query must be processed every time the view is used. If you create complex views with multiple joins and filters, or if you nest views, you may find that performance is dramatically degraded. Be sure you test execution before deploying applications that use views extensively.
* Using views, you can write the underlying SQL once and then reuse it as needed.
* views are easy to create and even easier to use. Used correctly, views can greatly simplify complex data manipulation.

Lesson 19:
* Because stored procedures are usually stored in a compiled form, the DBMS has to do less work to process the command. This results in improved performance.

Lesson 21:
* Cursors are used primarily by interactive applications in which users need to scroll up and down through screens of data, browsing or making changes.

Lesson 22:
* Performing client-side checks is a time-consuming process. Having the DBMS do the checks for you is far more efficient.
* Primary key values can never be reused. If a row is deleted from the table, its primary key must not be assigned to any new rows.
* After a foreign key is defined, your DBMS does not allow the deletion of rows that have related rows in other tables. * Cascading delete. If enabled, this feature deletes all related data when a row is deleted from a table.
* Indexes improve the performance of retrieval operations, but they degrade the performance of data insertion, modification, and deletion. When these operations are executed, the DBMS has to update the index dynamically.
* Indexes are used for data filtering and for data sorting. If you frequently sort data in a specific order, that data might be a candidate for indexing.* It is always a good idea to revisit indexes on a regular basis to fine-tune them as needed.
* As a rule, constraints are processed more quickly than triggers, so whenever possible, use constraints instead.



iPhone dev Stupidity 54: Convert rect of zero size

When the rect's width/height is zero, UIView method: convertRect:toView: will not work - it just returns the rect passed in.

To fix:

- (CGRect) extConvertRect: (CGRect) rect toView: (UIView *) view{


if(rect.size.width == 0 || rect.size.height == 0){


CGPoint lt = [self convertPoint: rect.origin toView: view];


return CGRectMake(lt.x, lt.y, rect.size.width, rect.size.height);


}else{


return [self convertRect:rect toView: view];


}


}


iPhone dev Stupidity 53: Read the Human Interface Guide

Sure there's lots of "SHOULD" in the HIG:


"Note that although the touch and hold gesture is the primary way users reveal the edit menu, they can also double-tap a word in a text view to select it and reveal the menu at the same time. If you support the menu in a custom view, you should respond to both gestures. In addition, you can define the object that is selected by default when the user double taps."


"If you support the Cut, Copy, and Paste commands in your application, you should also support undo and redo (described in“Supporting Undo and Redo”). This is because the edit menu does not require confirmation before the actions are performed and users often expect to be able to undo recent operations if they change their minds."


And sure, they're very good advice - unless you just want get rejected by app store.

iPhone dev Stupidity 52: Print frame in GDB

To print the frame in gdb:


(gdb) p (CGRect)[self frame]


$1 = {


  origin = {


    x = 12, 


    y = 150


  }, 


  size = {


    width = 72, 


    height = 49


  }


}



You can also 
 po self

iPhone dev Stupidity 51: Unit test - how to debug?

XCode doesn't support iPhone unittest very well. 

After trying very hard to setup the SenUnitTest for iPhone, you'll find it can not be injected test - which means your app can't link into the unittest target for symbol resolving. Then you give up and build a non-injected unittest target, build and the test runs. It seems everything is OK.

But when there's a failure, you CAN'T DEBUG it. XCode's unit test use kind of shell script to drive the testing - the failure is buried far away from the debugger. It's really annoying. Robert Martin once said that with unit test he uses debugger less and less - but he doesn't mean he can live without a debugger.

So I switch to google-toolbox-for-mac. It's really sample - using the same SenUnitTest code with iPhone and without too much setup headache. Just a standalone iPhone app with all your test code in it - no magic.

iPhone dev Stupidity 50: Base SDK when migrating to iPhone OS 3.0

Remember to change the Base SDK, for those frameworks used by your project is relative to this SDK.



XCode doesn't change it for you - If you use some new 3.0 features (like UIPasteboard), XCode will search it from the base SDK folder - which will result a failure when it fails to find the new 3.0 frameworks.

iPhone dev Stupidity 49: Reverse a string

If you don't want to rewrite one, check this:


-(NSString *) reverseString
{
NSMutableString *reversedStr;
int len = [self length];
 
// Auto released string
reversedStr
= [NSMutableString stringWithCapacity:len];
 
// Probably woefully inefficient...
while (len > 0)
[reversedStr appendString:
[NSString stringWithFormat:@"%C", [self characterAtIndex:--len]]];
 
return reversedStr;
}

iPhone dev Stupidity 48: Launching SMS



From [iPhone Developer:Tips]

"Also not supported by the iPod Touch, is the ability to quickly setup the SMS client so that your users can quickly send a text message. It is also possible to provide the body of the text message.

The format looks like this:

sms:${PHONENUMBER_OR_SHORTCODE}

NOTE: Unlike other URLs, an SMS url doesn’t use the “//” syntax. If you add these it will assume it is part of the phone number which is not.

1
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"sms:55555"]];

NOTE: According to the official SMS specification, you should be able to send a body as well as the phone number by including “?body=” parameter on the end of the URL … unfortunately Apple doesn’t seem to support this standard."


There's also an article on Launching your app using custom URL scheme.

iPhone dev Stupidity 47: Pixel position, int or float?

iPhone draws at float level.

If you use int - after some rounding, the pixel will be wrongly positioned.

iPhone dev Stupidity 46: retain vs asign - who's the owner?

Don't use retain just because it's convenient.

If a child holds a reference to it's parent, it's not a retain - from the life time perspective, when the parent get released, the child will be released. It's an assign.

If the child retain the parent: 

parent new 0 -> 1
child -> parent 1 -> 2
parent release 2 -> 1

The parent will have no chance to get released with the extra retain.

iPhone dev Stupidity 45: Ensure subclass override some func

Some member function is intended to be overridden (kind of pure virtual function in C++).

To force this request, use:

assert(NO && "sub class should overriding");


iPhone dev Stupidity 44: Call virtual function in Ctor

Yes, you can do this in Objective-C - even if the func to override is private.

Some interesting pattern for Ctor - like template method. Defer some specific task to subclass and do the general routine ones in parent.

iPhone dev Stupidity 43: Stop at assertion failure

When XCode meets an assertion failure, it simply exits - without any stack trace. 

It's really annoying. 

You can set a breakpoint at assertion failed entry:

(gdb) b __assert_rtn

Then the debugger will stop properly with the stack trace.


// defined in assert.h

#if __DARWIN_UNIX03


#define assert(e) \


    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)


#else /* !__DARWIN_UNIX03 */


#define assert(e)  \


    (__builtin_expect(!(e), 0) ? __assert (#e, __FILE__, __LINE__) : (void)0)


#endif /* __DARWIN_UNIX03 */



iPhone dev Stupidity 42: use category for convenient methods

These are nice for UIView and they can be declared as properties:

@property (readonly, nonatomic) int width;


@property (readonly, nonatomic) int height;


@property (readonly, nonatomic) int x;


@property (readonly, nonatomic) int y;


@property (readonly, nonatomic) int centerX;


@property (readonly, nonatomic) int centerY;


@property (readonly, nonatomic) int right;


@property (readonly, nonatomic) int bottom;



- (int) width{


return (int) self.frame.size.width;


}




- (int) height{


return (int) self.frame.size.height;


}




- (int) x{


return (int) self.frame.origin.x;


}




- (int) y{


return (int) self.frame.origin.y;


}




- (int) centerX{


return self.center.x;


}




- (int) centerY{


return self.center.y;


}




- (int) right{


return CGRectGetMaxX(self.frame);


}




- (int) bottom{


return CGRectGetMaxY(self.frame);


}



iPhone dev Stupidity 41: drawing a shadow

From StackOverflow:


Any drawing that should be affected by the shadow setting needs to happen after

CGContextSetShadow(currentContext, CGSizeMake(-15, 20), 5);

but before

CGContextRestoreGState(currentContext);


There's also some sample code in Apple's Quartz 2D Programming Guide. Make sure you didn't draw the shadow out of the view's bounds.

iPhone dev Stupidity 40: Gradient

Make Background of UIView a Gradient Without Sub Classing

You can use +[UIColor colorWithPatternImage:] to produce a patterned background. Example (bring your own CGGradient):

// Allocate bitmap context
CGContextRef bitmapContext = CGBitmapContextCreate(NULL, 320, 480, 8, 4 * 320, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaNoneSkipFirst);
// Draw Gradient Here
CGContextDrawLinearGradient(bitmapContext, myGradient, CGPointMake(0.0f, 0.0f), CGPointMake(320.0f, 480.0f), );
// Create a CGImage from context
CGImageRef cgImage = CGBitmapContextCreateImage(bitmapContext);
// Create a UIImage from CGImage
UIImage *uiImage = [UIImage imageWithCGImage:cgImage];
// Release the CGImage
CGImageRelease(cgImage);
// Release the bitmap context
CGContextRelease(bitmapContext);
// Create the patterned UIColor and set as background color
[targetView setBackgroundColor:[UIColor colorWithPatternImage:image]];

iPhone dev Stupidity 39: What's new in iPhone OS 3.0?

Several good tutorial:


They still doesn't have an in-app SMS sending.

iPhone dev Stupidity 38: target action

from Apple's Doc: 

Target-Action in UIKit:

You set up a control so that it sends an action message to a target object by associating both target and action with one or more control events. To do this, send addTarget:action:forControlEvents: to the control for each target-action pair you wish to specify. When the user touches the control in a designated fashion, the control forwards the action message to the global UIApplication object in a sendAction:to:from:forEvent:message. As in the Application Kit, the global application object is the centralized dispatch point for action messages. If the control specifies a nil target for an action message, the application queries objects in the responder chain until it finds one that is willing to handle the action message—that is, one implementing a method corresponding to the action selector.

iPhone dev Stupidity 37: Keyboard Size

If you don't want to hard code the keyboard size or position

From here:

  1. [[NSNotificationCenter defaultCenter] addObserver:self  
  2.                                          selector:@selector(keyboardNotification:)  
  3.                                              name:UIKeyboardWillShowNotification  
  4.                                            object:nil];  

The keyboardNotification method looks like this:
  1. - (void)keyboardNotification:(NSNotification*)notification {  
  2.     NSDictionary *userInfo = [notification userInfo];  
  3.     NSValue *keyboardBoundsValue = [userInfo objectForKey:UIKeyboardBoundsUserInfoKey];  
  4.     [keyboardBoundsValue getValue:&keyboardBounds];  
  5. }  


iPhone dev Stupidity 36: Warning - "modifying layer that is being

How-To: Solve ‘modifying layer that is being finalized’ iPhone SDK

"The best way to solve this (that I’ve found – please post a comment if you can provide a better one) is to remove the view from it’s superview rather than release it:"

[self.popupPreviewView removeFromSuperview];
self.popupPreviewView = nil;


The point here is that if you release the subview directly, later on when the superview tries to do something (displaying etc) in the following event loop - error will happen.
So it's a best practice to remove from parent view.

iPhone dev Stupidity 35: NSZombie and Instruments Leak

If you enabled NSZombie  :



"NSZombieEnabled is an environment variable which controls whether the Foundation runtime will use zombies. When zombies are enabled, a deallocated object's class is dynamically changed to be _NSZombie, and by default, the memory region is never marked as free, although this can be controlled separately."

When instruments sees these Zombie objects, it takes them as leaks:


So, better turn off the NSZombieEnabled option when instruments.

For more info about NSZombie, check XCode 3 Unleashed P388 (Chap 22. More about Debugging).




iPhone dev Stupidity 34: NSUInteger

NSArray.count is NSUInteger.

Which means for code:

texels_.count <= -1

It's a unsigned int comparison: -1 will be converted to a 0xFFFFFFFF and the result is TRUE.


The ugly thing about this promotion is that there's no any warning.


iPhone dev Stupidity 33: Line width

from StackOverflow:

"The behaviour you are seeing stems from the fact that cocoa's drawing routines draw lines centered around the pixel positions on which you ask them to. Let me explain.

The straight lines that you are drawing fall on the very edge of the button's rectangle. When your drawing routine is called, Cocoa has conveniently set the clipping region to the exact boundary of the button rectangle, but when you ask Cocoa to draw a line along the edge, exactly half of the line is drawn outside of the clipping rectangle.

You notice the difference in the rounded corners because the curved portion falls completely inside the clipping rectangle, so none of it is clipped away."

iPhone dev Stupidity 32: More UIScrollView Pains and Solutions

Some pain, some gain:

1.  iPhone: advanced UIScrollView tricks everyone should know
4.  Are there any good UIScrollView Tutorials on the net?

Most of the link are from StackOverflow.

iPhone dev Stupidity 31: tracking touch in scrollview



[self setCanCancelContentTouches:NO]

canCancelContentTouches

A Boolean value that controls whether touches in the content view always lead to tracking.

@property(nonatomic) BOOL canCancelContentTouches

Discussion

If the value of this property is YES and a view in the content has begun tracking a finger touching it, and if the user drags the finger enough to initiate a scroll, the view receives a touchesCancelled:withEvent: message and the scroll view handles the touch as a scroll. If the value of this property is NO, the scroll view does not scroll regardless of finger movement once the content view starts tracking.


* A life-saving property - reading again from Apple Sample Code: UIScrollViewSuite - AutoScroll.

iPhone dev Stupidity 30: Size of space in different system font

Size of space in different system font:

---------------------------

font 10: width 3, height 13


font 11: width 3, height 14


font 12: width 3, height 15


font 13: width 4, height 16


font 14: width 4, height 18


font 15: width 4, height 19


font 16: width 4, height 20


font 17: width 5, height 21


font 18: width 5, height 22


font 19: width 5, height 23


font 20: width 6, height 24


font 21: width 6, height 26


font 22: width 6, height 27


font 23: width 6, height 28


font 24: width 7, height 29


font 25: width 7, height 30


font 26: width 7, height 31


font 27: width 8, height 33


font 28: width 8, height 34


font 29: width 8, height 35


font 30: width 8, height 36


font 31: width 9, height 37


font 32: width 9, height 38


font 33: width 9, height 39


font 34: width 9, height 41


font 35: width 10, height 42


font 36: width 10, height 43


font 37: width 10, height 44


font 38: width 11, height 45


font 39: width 11, height 46


font 40: width 11, height 47


font 41: width 11, height 49


font 42: width 12, height 50


font 43: width 12, height 51


font 44: width 12, height 52


font 45: width 13, height 53


font 46: width 13, height 54


font 47: width 13, height 56


font 48: width 13, height 57


font 49: width 14, height 58


iPhone dev Stupidity 29: ScrollView, Order Matters

If setting a scrollview's zoomScale before it's added to superview, the scrollview will refuse to scroll.

iPhone dev Stupidity 28: UIScrollView Sample Code Reading

1. Tap to Zoom:






Some resource on UIScrollView:
1. Scrolling with two fingers (StackOverflow).
2. Jeff LaMarche on scrollview.
3. Implementing tap to zoom(jonathanwatmough.com).
4. Apple Sample Code: Scrolling.
5. Apple Sample Code: ScrollViewSuite - the most valuable one.

Tuesday, June 23, 2009

iPhone dev Stupidity 27: Rect in different views

When moving a view to it's superview, instead of padding/fixing rect position of a rect:

use convertRect:fromView:

Monday, June 22, 2009

iPhone dev Stupidity 26: Position

for an array index : 0 1 2 3 ...

if you insert between 2 and 3, the index of the inserted element is still 2.

Friday, June 19, 2009

iPhone dev Stupidity 25: Read The Sample Code of Apple

While hunting around for a draw-round-rect function, I forget that there's already a fucnction: fillRoundRect in HeadsUpUI of apple's sample code.

I really should read more code.


Wednesday, June 17, 2009

iPhone dev Stupidity 24: Unit Test Setup

* Sen:Te's guide


Configure the project

1. Add a ‘Unit Tests’ target

From the Project > New Target… menu add a Mac OS X > Cocoa > Unit Test

2. Configure ‘Unit Tests’ through its inspector:

In the ‘Build’ tab delete all ‘User-Defined Settings’ and the ‘Other Linker Flags’ setting.

In the ‘General’ tab add the Foundation and SenTestingKit frameworks

(/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator2.2.sdk/Developer/Library/Frameworks/SenTestingKit.framework)

3. Make the application a dependency of ‘Unit Tests’:

In the ‘General’ tab of the application add ‘UnitTests’ as a direct dependency.
Write some tests

4. Avoid compiling tests outside of the simulator:

 #include "TargetConditionals.h" 
 #if !TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR 
 // the SenTestCase implementation goes here... 
 #endif

* StackOverflow discuss:


If you right click on your unit test target and select the "get info" menu you will see your target options. At the bottom of the pane, you'll see a section called "User Defined": remove the entry containing the path to cocoa.h. I don't remember the name of this entry as I removed it, but this fixes the same problem I had before.

I also changed Base SDK to be Device - iPhone OS 2.2 and other linker flags to -framework Foundation -framework SentestingKit

Tuesday, June 16, 2009

iPhone dev Stupidity 23: Keep Iterator Valid when Removing Object

Just the same as C++, when deleting objects in an NSMutableArray from head to tail, the iterator/index after the deleting point will be invalid.

To solve: delete from tail to head.

iPhone dev Stupidity 22: Forget to Remove from Superview

When removing a subview from your array, remember to remove it from superview. Or it will stick on the screen and refuse to refresh.

Monday, June 15, 2009

iPhone dev Stupidity 21: Binary Search

Don't need to re-invent for Obj-C, use :

CFArrayBSearchValues

iPhone dev Stupidity 20: Animation Fast

From StackOverflow:

"Creating 30 new animations a second is a really bad idea, and not how Core Animation was intended to be used. Core Animation was designed around the idea that you tell the system where you want your layer (or layer-backed view) to end up, and it figures out the rest, including how many frames to drop to run the animation in the time frame you provide. The animations themselves will run on a background thread, but I believe there's a little setup that needs to be performed first which takes place on the calling thread (usually the main thread). This setup might take longer than 1/30th of a second, which would overload your main thread.

You goal should be to minimize the amount of interaction with Core Animation. If you have a complex, but scripted, motion path (or other property change), set it all up ahead of time using a CAKeyframeAnimation and just call that animation once. If there's something about the motion of your object that needs to be altered in response to user input, only do that when you get the actual input. Changing a property of a CALayer mid-animation will cause it to smoothly move from the middle of its current motion path to its new destination.

If you work with Core Animation in this fashion, you can simultaneously animate up to 50 moving translucent layers at 60 FPS on the iPhone."


Sunday, June 14, 2009

iPhone dev Stupidity 19: using shark for iPhone


*) Download your app to the iPhone as usual, you want a release build for performance testing
*) Launch the app on the device
*) Launch /Developer/Applications/Performance Tools/Shark in the Finder
*) Choose Sampling>Network/iPhone menu item
*) Choose your device in the window
*) Choose the application from the popup menu under Target so only your app is sampled
*) Click Start button in window
*) Do stuff in test application
*) Click Stop in window

iPhone dev Stupidity 18: Disable iPhoto When iPhone connected

You can disable it from image capture settings.



Tuesday, June 09, 2009

iPhone dev Stupidity 17: Clip Image from CGContext


// create CGImageRef frome UIView context

CGImageRef imageref;

imageref = CGBitmapContextCreateImage(context);


// convert CGImageRef to UIImage;

UIImage *uiImage;

uiImage =[UIImage imageWithCGImage:imageref];

CGImageRelease(imageref);

Monday, June 08, 2009

iPhone dev Stupidity 16: Subview Index

* how to get subview's index?

Iterating the subviews array and compare:

"I think what you want to do is check the subviews NSArray of your superview or UIWindow and check that. I can't remember which is the front, but it is either the first or last object.
Subviews are drawn with the painter's method. The views are drawn in order from farthest to nearest and the last object drawn is "the front.""

Sunday, June 07, 2009

iPhone dev Stupidity 15: Category Limitation

* Detail of category's implementation

Here's a guess:

Category is implemented by attaching additional slots at the tail of the vtbl (virtual function table). It's based on the fact that there's only one copy of vtbl for a class - if we define a category, the compiler could extend the vtbl for several slots for the newly added member functions.


* Why can't category add ivar?

Because for the well-known class like NSObject, all the libraries may use it as base class - and they're in binary. We have no way to change the layout of the object for compiled code.

So it's not able to simulate multi-inheritance gracefully.

Saturday, June 06, 2009

iPhone dev Stupidity 14: UIFont size

To understand the properties of UIFont (from Microsoft doc on opentype ):


 



Log info for a 42 pointsized system font:


> font size 21 50

> Font Helvetica properties: leading 50.000000, ascender 39.340820, capheight 30.534000, descender -9.659180, pointSize 42.000000


Leading: the height of the line.


To get the tight bounding box of a character, height = ascender.


And to center a char at the center of a view:


 


- (CGRect) centerRectForChar: (NSString*) txt{
 CGSize font_size = [text_ sizeWithFont: font_];
 int x = (VIEW_WIDTH/2) - (font_size.width/2);
 int y = (VIEW_HEIGHT/2) - (font_size.height/2);
 int w = font_size.width;
 int h = font_.ascender;

 return CGRectMake(x, y, w, h);
}

Thursday, June 04, 2009

iPhone dev Stupidity 13 - Transparent View

* how to cover a transparent/Glass view onto an opaque view?

The trick from Jeff LaMarche's Blog:

"here's the point to remember today: if you need objects below yours to show through parts of your view without using alpha, the backgroundColor property MUST be set to [UIColor clearColor]. This is true even if you do not call drawRect on super.

The other thing you need to do is make sure that the 
opaque property is set to NO. Ordinarily, opaque should be set to YES as an optimization, but that optimization isn't available to us if we want stuff to show through from below."

Messing with alpha does show the view under cover through - but with kind of sick effect: everything is just blurred. If you want to draw something on this glass view, prefer to Jeff's approach.

iPhone dev Stupidity 12

* awakeFromNib vs initWithFrame


 "Note that you have to implement this and not using the initWithFrame method that the x-code template gives you as nib controlled views don't use initWithFrame (from the apple documentation)."