Getting a List of 5 recent items filled in UITextField - iphone

Getting a List of 5 recent items filled in Text Field, from where if i select any item will get populated in the Text Field. Open for any suggestions/solution.
Thanks in Advance.

I agree with Paul Peelen but his solution is incomplete. You want to have five different items, so the code is the following:
#define CAPACITY 5
[...]
self.recents = [NSMutableArray arrayWithCapacity:CAPACITY + 1];
[...]
- (void)addItem:(NSString*)addItem {
//item won't be twice in the list
[self.recents removeObject:item];
//recently used items are at the beginning of the list
[self.recents insertObject:item atIndex:0];
//remove the sixth item
if ([self.recents count] == CAPACITY + 1) {
[self.recents removeLastObject];
}
}

Create a NSMutableArray and listen to the UITextField's delegate. Whenever the user presses "Return" or the field is resigned, add the current value to the NSMutableArray ([myArray addObject:textField.text];)
When you want to show the data in the array:
for (NSString *value in myArray)
{
NSLog(#"String value: %#", value);
}

Related

UITableViewWith Paging Prev,next button

I have one NSMutableArray that has number of records (suppose 52).
for (int i=0;i<=52;i++) {
[arrSavedCalculation addObject:[NSString stringWithFormat:#"Bianca lb,Red %d",i]];
}
I want to give a paging Prev and Next button at bottom of tableview. and each page display 6 record.How can i do this. i also see this document but not success
http://www.ke-cai.net/2011/04/pagination-with-uitableview-in-ios.html
Try with these. Tested and found working. Can be improved.
#interface ViewController (){
//pageNumber will hold the current page index
NSInteger _pageNumber;
//keeping the max page number for ease of calculation
NSUInteger _maxPageNumber;
//the batch size
NSUInteger _numberOfVisibleRows;
}
#end
#implementation ViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
//Main data array is formed
NSUInteger rows = 0;
NSMutableArray *tempArray = [NSMutableArray array];
while (rows<52) {
[tempArray addObject:[NSString stringWithFormat:#"Item %d",rows+1]];
rows++;
}
self.mainArray = [NSArray arrayWithArray:tempArray];
_pageNumber = 0;
_numberOfVisibleRows = 5;
_maxPageNumber = [self.mainArray count]/_numberOfVisibleRows;
self.subArray = [self subArrayForPageNumber:_pageNumber];
}
- (NSArray *)subArrayForPageNumber:(NSUInteger)pageNumber{
NSRange range = NSMakeRange(_pageNumber*_numberOfVisibleRows, _numberOfVisibleRows);
if (range.location+range.length>[self.mainArray count]) {
range.length = [self.mainArray count]-range.location;
}
return [self.mainArray subarrayWithRange:range];
}
- (IBAction)buttonPressed:(UIBarButtonItem *)button{
//Same method is used for calculating the page numbers
if (button.tag ==1) {
_pageNumber= MIN(_maxPageNumber, _pageNumber+1);
}else{
_pageNumber = MAX(0, _pageNumber-1);
}
self.subArray = [self subArrayForPageNumber:_pageNumber];
[self.tableView reloadData];
}
Source Code
you should take two array.
1) Your MAIN ARRAY containing all of objects.
2) A Temporary array contain only 6 objects.
While loading tableview use that Temporary Array.
keep a page counter which will count your current page.
According to your 52 objects you can have 52/6 = 9 page but last page contain only 4 object.
like.
#define kNumberOfObjectInOnePage 6
set self.page=0 in "viewDidLoad" //self.page is the page counter.
-(void)nextPage:(id)sender{
self.page++;
take 6 objects from main array into temp array
reload your table view.
}
-(void)previous:(id)sender{
self.page--;
take 6 previous object into temp array
reload your table view.
}
A simple solution is if you are accessing records from web service then ask to him provide the total number of records in initial hits as well as first 6 records to display. If you want to do paging you should keep page 0 or 1 at initial hit to service and as you got 6 records on first page and you find that total records which are given from service is more than the 6 then you have to show previous and next button otherwise no need of these button.
As you accessing the records you have to put into in an NSArray or in Coredata. When you press next buttonyou have to increase the page count and fetch next 6 records and save to DB or array and reload the table.
if you press previous button you have to remove last 6 object from array or you can delete or check some kind last 6 records to display and reload table.
Hope this helps.

Search for strings in large array takes a long time

I'm implementing a search field that filters a UITableView according to the text the user enters.
The TableView is built from an array that holds NSStrings (the data to display and search) and may contain 6000+ items.
When the user starts the search, I'm implementing the -(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText method.
My code works, however, when the data array is large, it is very slow and creating a really bad user experience (my iPhone 4s get stuck for a good few seconds).
The way I'm implementing the search (in the method mentioned above) is this:
NSMutableArray *discardedItems = [[NSMutableArray alloc] init]; // Items to be removed
searchResultsArray = [[NSMutableArray alloc] initWithArray:containerArray]; // The array that holds all the data
// Search for matching results
for (int i=0; i<[searchResultsArray count]; i++) {
NSString *data = [[containerArray objectAtIndex:i] lowercaseString];
NSRange r = [data rangeOfString:searchText];
if (r.location == NSNotFound) {
// Mark the items to be removed
[discardedItems addObject:[searchResultsArray objectAtIndex:i]];
}
}
// update the display array
[searchResultsArray removeObjectsInArray:discardedItems];
[myTableView reloadData];
I did not think that looping over an array with a few thousand items would cause any issue...
Any suggestion will be appreciated!
UPDATE
I've just realized that what takes most of the time is this:
[searchResultsArray removeObjectsInArray:discardedItems];
Try fast enumeration way, my snippet:
- (void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)text
{
if(text.length == 0)
{
self.isFiltered = NO;
}
else
{
self.isFiltered = YES;
self.searchArray = [NSMutableArray arrayWithCapacity:self.places.count];
for (PTGPlace* place in self.places)
{
NSRange nameRange = [place.name rangeOfString:text options:NSCaseInsensitiveSearch];
if(nameRange.location != NSNotFound)
{
[self.searchArray addObject:place];
}
}
}
[self.tableView reloadData];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(self.isFiltered)
return self.searchArray.count;
else
return self.places.count;
}
In cellForRowAtIndexPath:
PTGPlace *place = nil;
if(self.isFiltered)
place = [self.searchArray objectAtIndex:indexPath.row];
else
place = [self.places objectAtIndex:indexPath.row];
// Configure the cell...
cell.textLabel.text = place.name;
cell.detailTextLabel.text = [place subtitle];
Try this:
for the first three positions, create 26 index sets, each representing the array index of items with that letter (just lower case). That is, say a entry at idx=100 starts with "formula". The index set representing "f" in the first position will contain the index "100". The index set for the second character 'o' will contain the index 100, and the index set for the third character 'r' will contain 100.
When the user types the character 'f', you immediately have the index set of all array items starting with 'f' (and can create a subset of your major array quickly). When an 'o' is typed next, you can find the intersection of indexes in the first match with the second match. Ditto for the third. Now make a subarray of the major array that had the first three indexes match - you can just use the index sets for this.
Using this drastically reduced array, you can now do brute force matching as you were doing originally.

NSNumber stores zero value instead of the correct numeric value

I developing a simple calculator iPhone application. Just for practicing purpose. I have an IBAction method that stores the digits that the user entered. The whole concept is that the calculator app piles up pending oprations so the user can perform multiple actions and the screen shows the result the following way: 1 + 2 - 4 + 10 = X. So i have two NSMutableArray that stores NSNumber numbers and the operator actions. When the user clicks an operator button, a new array element created for the new number. When the users entering the digits, the last array element is updating itself until an operator button is pressed.
The problem is that every array element is zero. Inside the method it stores the corrent value when i set it, but when the method is executed and called again it contins nothing but zeros instead of the entered numbers. The NSNumber objects are present, the array contains every number, but every number is 0.
Here is the method:
// Processing digit buttons
- (IBAction)clickDigit: (UIButton *) sender {
double currentNumber = [[numbers lastObject] doubleValue];
// Get the digit
double digit = sender.tag;
// Do nothing when the currentNumber and the digit both zero
if(currentNumber == 0 && digit == 0) {
return;
}
// When currentNumber is zero, override the value
if(currentNumber == 0) {
currentNumber = digit;
[numbers removeLastObject];
[numbers addObject: [NSNumber numberWithDouble: currentNumber ]];
// Else, add the digit to currentNumber
} else {
currentNumber = currentNumber * 10 + digit;
[numbers removeLastObject];
[numbers addObject: [NSNumber numberWithDouble: currentNumber ]];
}
// Update the screen
[self updateDisplay];
}
I have no clue what's wrong. Any suggestions?
Thanks in advance
UPDATE: it turns out that the clickClear method is automatically called after each button press. It sets the value zero. I linked the full source code below this post in the comment section. The only question is: why this method called? What calls this method?
UPDATE2: with The Saad's help i managed to solve this problem. Thanks to everyone! :)
The only possible way you get this problem is if sender.tag == 0 all the time. So you should definitely check that. My point here is that there is not other possible scenario that produces those symptoms, so it has to be it.
ok got it,
one thing here is that first check your sender's tag, either by braekpoint or by NSLog in click Digit method, i guess tags never gets up than zero, and hence the last object in array will always be zero, further, place nslog or breakpoint on all places where you are adding object to array.
in interface.
#property(nonatomic, retain) NSMutableArray* numberArray;
in implementation,
#synthesize numberArray = _numberArray;
in dealloc
[_numberArray release];
ok now next thing is to make an array in init which is
NSMutableArray* arr = [NSMutableArray alloc] init];
self.numberArray = arr;
[arr release];
[self.numberArray addObject:[NSNumber numberWithDouble:0]];

How can I create array objects from UITextFields?

How can I create array objects from UITextFields? I also want an if statement for each object to check if the UITextField's text length is more than 1.
How can I do this using this core code?:
maincelltext = [[NSArray alloc] initWithObjects:#"UITextField 1 Content Here",#"UITextField 2 Content Here",#"UITextField 3 Content Here",#"UITextField 3 Content Here",nil];
Thanks!
Use NSMutableArray instead, and addObject: if(textField1.text.length > 1) then [yourMutableArray addObject:textField1.text]; and so on...
Something like this:
// in your interface
UITextField * textField1;
UITextField * textField2;
UITextField * textField3;
NSMutableArray * mainCellTextArray;
//implementation
mainCellTextArray = [[NSMutableArray alloc] init]; // release it later
if(textField1.text.length > 1)
{
[mainCellTextArray addObject:textField1.text];
}
if(textField2.text.length > 1)
{
[mainCellTextArray addObject:textField2.text];
}
if(textField3.text.length > 1)
{
[mainCellTextArray addObject:textField3.text];
}
Instead of creating an NSArray, I would use a IBOutletCollection and add all the UITextFields to it. You can do this easily through Interface Builder. To loop through and check that each has a text length of more than one is easily done whether you use NSArray or IBOutletCollection. Just use any of the many looping constructs (i.e. for, for-in) and check each item's text property's length.

How to prevent counting an empty NSMutableArray

I would like to simulate the SMS Bubbles of the iPhone for my own app. I found some nice code overhere (FYI): http://vimeo.com/8718829 . It is a restyled UITableView. Exactly what a wanted.
Here is the problem:
- The Tableview is filled with an array of messages
- It needs to be a NSMutable array because you want to add messages on the fly.
- When there are no messages yet, the message-array is empty.
- But counting an empty NSMutableArray causes an exeception, the app crashes. (you need the count for scrolling).
So what is a nice solution for that? I now pre fill the array with "". But that is very ugly. You see a mini bubble on the screen.
Can you hide cells? In the example on the video, there are already 2 messages so the problem does no occur.
Any suggestion is welcome. Tnx
Christian
Actually counting an empty array does not raise any exception. I think the problem is here:
- (void)add {
if(![field.text isEqualToString:#""])
{
[messages addObject:field.text];
[tbl reloadData];
NSUInteger index = [messages count] - 1;
[tbl scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
field.text = #"";
}
}
As the "-1" index cannot exist. You can edit that line to
NSUInteger index = MAX(0, [messages count] - 1);
And it should work.
You can count an empty array (I assume you mean [arrayName count]) as long as its alloc'd so make sure its initialized somewhere earlier.