http://uihacker.blogspot.com/2009/01/iphone-custom-font-loading-complete.html (must see)
http://www.iphonedevsdk.com/forum/iphone-sdk-development/1285-custom-fonts.html
http://discussions.apple.com/thread.jspa?threadID=1447085&tstart=0
Tuesday, May 26, 2009
Wednesday, May 6, 2009
Sunday, May 3, 2009
Saturday, May 2, 2009
iPhone webkit Related Blogs
Found some blogs on iPhone webkit, while actually looking for something else:
* Web log of Matteo Spinelli
* iPhoneized - Nurturing iPhone friendly web design
* Web log of Matteo Spinelli
* iPhoneized - Nurturing iPhone friendly web design
Thursday, April 30, 2009
Alternative of NSPredicate on iPhone SDK
Use following classes:
The SearchPredicate.h
And the SearchPredicate.m
And here is how to use it with UISearchBar:
Notice that I was using NSPredicate (sp) with filteredArrayUsingPredicate method of NSMuteableArray before. However as I have not implemented that method for our new class yet (you can do this, I guess using categories etc., and post back in comments) I have commented it and using a for loop and evaluateWithObject on each object of NSMuteableArray to have the same effect.
The SearchPredicate.h
// SearchPredicate.h
//
// Created by Yasir Ibrahim on 24/12/08.
#import <UIKit/UIKit.h>
@interface SearchPredicate : NSObject {
NSString* searchTerm;
}
@property (nonatomic, retain) NSString* searchTerm;
- (BOOL)evaluateWithObject:(id)object;
@end
And the SearchPredicate.m
// SearchPredicate.m
// Created by Yasir Ibrahim on 24/12/08.
#import "SearchPredicate.h"
@implementation SearchPredicate
@synthesize searchTerm;
- (BOOL)evaluateWithObject:(id)object
{
searchTerm = [searchTerm stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if([searchTerm compare:@"*"] == 0 || [searchTerm compare:@""] == 0)
{
return TRUE;
}
NSString* name = [object objectForKey:@"Name"];
if([name length] >= [searchTerm length])
{
NSRange r;
r.length = [searchTerm length];
r.location = 0;
if([name rangeOfString:searchTerm options:NSCaseInsensitiveSearch range:r].location != NSNotFound)
{
return TRUE;
}
else
{
return FALSE;
}
}
else
{
return FALSE;
}
}
@end
And here is how to use it with UISearchBar:
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[mySearchBar resignFirstResponder];
SearchPredicate* sp = [[SearchPredicate alloc] init];
sp.searchTerm = [mySearchBar text];
[pickerItemFilteredList release];
//pickerItemFilteredList = [pickerItemList filteredArrayUsingPredicate:sp];
pickerItemFilteredList = [[NSMutableArray alloc] init];
for(int i=0; i<[pickerItemList count]; i++)
{
if([sp evaluateWithObject:[pickerItemList objectAtIndex:i]])
{
[pickerItemFilteredList addObject:[pickerItemList objectAtIndex:i]];
}
}
[pickerItemFilteredList retain];
[myPickerView reloadComponent:0];
if([pickerItemFilteredList count] == 1)
{
[self showStoreOnMapAtRow:0];
}
}
Notice that I was using NSPredicate (sp) with filteredArrayUsingPredicate method of NSMuteableArray before. However as I have not implemented that method for our new class yet (you can do this, I guess using categories etc., and post back in comments) I have commented it and using a for loop and evaluateWithObject on each object of NSMuteableArray to have the same effect.
Tuesday, April 28, 2009
iPhone Related Business Blogs and Articles, I Just Read
- Indie iPhone developer (owned by John Casasanta and Sophia Teutschler) splits, shops around Where To application
- About FutureTap
- 'Where To' Sales Blog
- FutureTap's Ortwin Gentz Blog About His Buying 'Where To'
- How to Price Your iPhone App out of Existence
- Trouble in the (99-cent) App Store
- Free iPhone Icons
- They're Apps to Make Money - Story of Indie iPhone developers Todd Moore and Keith Shepherd in Washington Post.
Saturday, April 25, 2009
Strings in Objective C: Multiline String Literal, String Concatenation and String Formating
Here is an example of it:
Following link(s) were also helpful:
Java Developer’s Guide to String Constants in Objective-C
NSString* sql = [NSString stringWithFormat:@"select ID, aText, aFloat, aFloat2, "
"aText2 as myText2, aText3, 'aStringConstant' as myStringConstant "
"from myTable where afloat<=%1.6f and afloat2>=%1.6f Order by aText",
floatVariable, floatVariable2];
return [self executeQuery:[sql UTF8String]];
During my search I found this interesting blog.Following link(s) were also helpful:
Java Developer’s Guide to String Constants in Objective-C
Objective C and SQLite: Query Framework to Separate the Database Layer
After messing around with sqlite3_stmt*, sqlite3_prepare_v2, sqlite3_bind_double, sqlite3_step, sqlite3_column_int and sqlite3_column_text to run each query on sqlite (from my objectiveC code) and separate code for each time gathering the result in an NSMutableArray* and NSDictionary (for each row), I was thinking of a way to have a method that do it autometically by just giving the query, with no need to tell how to store the results.
After some research in sqlite documentation, I found sqlite3_get_table method (http://www.sqlite.org/c3ref/free_table.html), which I used in the following way:
Above code is capable of accepting any 'select' query and generate results in a standard data structure consist of NSMutableArray and NSMutableDictionary. Each element in the array represent a row, while each key-value pair in dictionary represent a column name and its value. Column name would be same as given in the query or as altered by 'as' keyword.
Using this method one can totally separate DB layer and application layer, and even in DB layer the method would be very short. Here is an example:
SQLite Version 3 C/C++ API Reference
Convenience Routines For Running Queries
After some research in sqlite documentation, I found sqlite3_get_table method (http://www.sqlite.org/c3ref/free_table.html), which I used in the following way:
+ (NSMutableArray*) executeQuery: (const char *) sql
{
MyAppDelegate *appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
char** azResult = NULL;
int nRows = 0;
int nColumns = 0;
char* errorMsg; //= malloc(255); // this is not required as sqlite do it itself
sqlite3_get_table(
[appDelegate getdb], /* An open database */
sql, /* SQL to be evaluated */
&azResult, /* Results of the query */
&nRows, /* Number of result rows written here */
&nColumns, /* Number of result columns written here */
&errorMsg /* Error msg written here */
);
if(azResult != NULL)
{
NSMutableArray* dataTable = [[[NSMutableArray alloc] init] autorelease];
nRows++; //because the header row is not account for in nRows
for (int i = 1; i < nRows; i++)
{
NSMutableDictionary* row = [NSMutableDictionary dictionaryWithCapacity:nColumns];
for(int j = 0; j < nColumns; j++)
{
NSString* key = [NSString stringWithUTF8String:azResult[j]];
NSString* value = [NSString stringWithUTF8String:azResult[(i*nColumns)+j]];
[row setValue:value forKey:key] ;
}
[dataTable addObject:row];
}
//free(errorMsg); // no need to free, sqlite somehow doing it
sqlite3_free_table(azResult);
return dataTable;
}
else
{
NSAssert1(0,@"Failed to execute query with message '%s'.",errorMsg);
return nil;
}
}
Above code is capable of accepting any 'select' query and generate results in a standard data structure consist of NSMutableArray and NSMutableDictionary. Each element in the array represent a row, while each key-value pair in dictionary represent a column name and its value. Column name would be same as given in the query or as altered by 'as' keyword.
Using this method one can totally separate DB layer and application layer, and even in DB layer the method would be very short. Here is an example:
Related Links
NSString* sql = [NSString stringWithFormat:@"select ID, aText, aFloat, aFloat2, "
"aText2 as myText2, aText3, 'aStringConstant' as myStringConstant "
"from myTable where afloat<=%1.6f and afloat2>=%1.6f Order by aText",
floatVariable, floatVariable2];
return [self executeQuery:[sql UTF8String]];
SQLite Version 3 C/C++ API Reference
Convenience Routines For Running Queries
Friday, April 17, 2009
ASP.NET: Accessing the GridView Row And Controls In It
There are some buttons in one of our ASP.NET project that are being directly generated from the sql query by spitting out html code. In grid view to show these buttons some fields are bound to the expression generating these buttons. The problem with these button was that we cannot set server side properties for them. Our developers had to set causevalidation = false for some of these button but they were unable to do so.
I thought of solving this issue by using a select command button changed to a templated field. However by changing a select button to a templated field it stops doing it function of selecting a grid row. To do that I planned to use the click event of this button and find this button in the grid by iterating over the rows, once found use that row index to select the row, which would trigger the selection change event. I implemented this idea as follows:
For some unknown reason this code was unable to find the control, as the control that is sending the event is something different then all the buttons in all the rows of grid.
Frustrated by this I tried to find this kind of topic on the internet. I found an answer on http://forums.asp.net/t/1137287.aspx.
Using that I reimplemented the method in following way:
The key in above code is using the NamingContainer property which is ideal to find the row in a grid situation. We will now use this method for finding different IDs (primary keys) when a templated button (will be implemented) for an action would be clicked.
The method bringMoreDetails() is being called as changing the selection is not triggering GridView_SelectedIndexChanged event.
I thought of solving this issue by using a select command button changed to a templated field. However by changing a select button to a templated field it stops doing it function of selecting a grid row. To do that I planned to use the click event of this button and find this button in the grid by iterating over the rows, once found use that row index to select the row, which would trigger the selection change event. I implemented this idea as follows:
protected void Button1_Click1(object sender, EventArgs e)
{
for (int i = 0; i < GridViewBiz.Rows.Count; i++)
{
if (GridViewBiz.Rows[i].FindControl("Button1").Equals(sender))
{
GridViewBiz.Rows[i].RowState = DataControlRowState.Selected;
break;
}
}
}
For some unknown reason this code was unable to find the control, as the control that is sending the event is something different then all the buttons in all the rows of grid.
Frustrated by this I tried to find this kind of topic on the internet. I found an answer on http://forums.asp.net/t/1137287.aspx.
Using that I reimplemented the method in following way:
protected void Button1_Click1(object sender, EventArgs e)
{
Button btnMoreDetails = (Button)sender;
GridViewRow row = (GridViewRow)btnMoreDetails.NamingContainer;
row.RowState = DataControlRowState.Selected;
bringMoreDetails();
}
The key in above code is using the NamingContainer property which is ideal to find the row in a grid situation. We will now use this method for finding different IDs (primary keys) when a templated button (will be implemented) for an action would be clicked.
The method bringMoreDetails() is being called as changing the selection is not triggering GridView_SelectedIndexChanged event.
Labels:
ASP.NET,
GridView,
GridViewRow,
NamingContainer,
template button
Thursday, April 16, 2009
Microsoft Access: How to Insert a Subdatasheet
I had two tables in my Access database, like category and subcategory such that the categoryId was being used as foriegn key in the subcategory table, however when I was opening the category table datasheet view it was not show a + sign to collapse and browse the subcategories. I remembered seeing this kind of view earlier and I remember that it happen when you make the relationships between the tables, so I went ahead and did that but it was now show that '+' sign in the datasheet view. I tried to find the older tables in which it was showing the '+' sign and found out that the type of relationship in them was "one-to-many" while some how in my case it was "intermediate", recreating the relationship automatically made it "one-to-many" and the problem solved.
During this investigation I also found that this can be done without actually setting up relationships. This is by going to insert menu selecting Subdatasheet and then selecting whatever table or query you want as subdatasheet and which column will actually link the tables.
During this investigation I also found that this can be done without actually setting up relationships. This is by going to insert menu selecting Subdatasheet and then selecting whatever table or query you want as subdatasheet and which column will actually link the tables.
Labels:
Datasheet,
Master-Child Fields,
Microsoft Access,
Subdatasheet
Subscribe to:
Posts (Atom)