I'm using UIRefreshControl in UITableviewController. The first time the table loads data coming from internet it automatically shows up at the top. See image below.
This is how I'm setting my refresh control
[self.refreshControl addTarget:self action:#selector(doRefresh:) forControlEvents:UIControlEventValueChanged];
- (void)doRefresh:(CKRefreshControl *)sender {
NSLog(#"Refreshing Parent");
// bring Data Here
}
This all happens before pull-to-refresh. First time when simple table data is populated the refresh control is shown instead of being hidden under the navigation bar.
Can anyone tell me why this is happening?
Try Allocating a new UIRefreshControl object and set the self.refreshControl to it. Something like that:
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl setAttributedTitle:[[NSAttributedString alloc] initWithString:#"Refreshing.."]];
[refreshControl addTarget:self action:#selector(doSomething:) forControlEvents:UIControlEventValueChanged];
self.refreshControl = refreshControl;
Hope it helps.
EDIT: Also you should use [self.refreshControl endRefreshing] at the end of the invoked selector.
Related
I have created a UIRefreshcontrol without a TableViewController. My question is how I would end it inside another method?
This is how I created it;
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self action:#selector(handleRefresh) forControlEvents:UIControlEventValueChanged];
[_tableView addSubview:refreshControl];
I discovered with help from #Justin Paulsson that this could be done;
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self action:#selector(handleRefresh:) forControlEvents:UIControlEventValueChanged];
[_tableView addSubview:refreshControl];
-
-(void) handleRefresh:(UIRefreshControl *)controller
{
//Refresh code
controller.endRefreshing;
}
The documented way is using an UITableViewController. Anything else can work, but as it's not documented, it may break on next iOS versions.
I'd just use an UITableViewController in your case.
It turns out that UIRefreshControl doesn't require a UITableView at all. refreshControl is a property of UIScrollView. You can set it on anything that inherits from UIScrollView, which includes UITableView of course, but also other classes such as UICollectionView.
I am using a custom Switch view controller and you would hope when switching between different views the "view did load" function or "view did finished loading" functions run but they do not.
Here what I am using:
- (IBAction)gotoKeyboardViews:(id)sender
{
YellowViewController *yellowController =
[[YellowViewController alloc]
initWithNibName:#"YellowViewController"
bundle:nil];
self.yellowViewController = yellowController;
[yellowController release];
[buttonKeyboard removeFromSuperview];
buttonStart = [UIButton buttonWithType:UIButtonTypeRoundedRect];
buttonStart.frame = CGRectMake(117,413, 103, 37);
[buttonStart setTitle:#"Restart" forState:UIControlStateNormal];
[buttonStart addTarget:self action:#selector(gotoBlueView:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:buttonStart];
[blueViewController.view removeFromSuperview];
[self.view insertSubview:yellowViewController.view atIndex:0];
}
gotoKeyboardViews suppose to switch the views To YellowView From BlueView...But I think I am a little bit off about implementing the navbar. Please don't tell me to go with the navbar because I don't like their rigidness in design.
The viewWillAppear method is executed as soon as the view gets active again. Maybe that's the hook you are searching?
Reference: Apple UIViewController Class Reference
those methods are only called when the nib file is loaded or the if you've override loadView. They will not get called again unless a new view controller is instantiated.
I do have the code for this, but since it's in so many files, I'll only narrow it down and post it if necessary. I believe I might just be missing some method call or thread thing... I have a navigation controller with a table view as its view and a toolbar with three buttons.
Touching one of the three buttons causes a method to be called that changes the table view's dataSource, reloads the table, and also changes the titles (and possibly number) of buttons on the toolbar (# of buttons can be 0~3).
There is also a rightBarButtonItem that pushes on a modal vc which, upon dismissal, changes the dataSource and reloads the table and buttons as well.
The problem: touching a button (#1) causes immediate effects: the buttons are redrawn with new titles and the tableView's data reloaded. But when the modal vc is dismissed (table's setter properties should cause data to be reloaded before viewWillAppear of the table vc), everything is fine except for the buttons! The correct number of UIBarButtonItems appear on the toolbar, but their titles are blank. I NSLog'd inside the method that sets the toolbarItems property, and after the log says "UIBBI array set", the buttons appear, with [blank] titles, then 4-5 seconds later, the titles appear (long after the method to set them has returned).
Do I need to be doing something in a different thread? Pushing this tvc on has no problems, and the method described in #1 also does not produce the same blank-then-titled effects... So, I'm stumped. Sorry for the LENGTHY explanation...trying to be complete. But any help would be very appreciated!
Code which is called when the self.resultsArray is updated (from this view, the previous one which pushes it on, or the modal:
- (void)updateBestGuessesButtons
{
if (self.resultsArray.count == 0 || self.resultsArray.count == 1 || !self.bestGuesses) {
[self.navigationController setToolbarHidden:YES animated:YES];
return;
}
[self.navigationController setToolbarHidden:NO animated:YES];
NSMutableArray *toolbarItems = [[NSMutableArray alloc] initWithObjects:[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil
action:nil], nil];
for (NSString *guess in self.bestGuesses) {
UIBarButtonItem *button = [[UIBarButtonItem alloc]
initWithTitle:guess
style:UIBarButtonItemStyleBordered
target:self
action:#selector(removeWordsWithLetter:)];
[toolbarItems addObject:button];
}
[toolbarItems addObject:[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil
action:nil]];
[self setToolbarItems:toolbarItems animated:YES];
}
It looks like you have to set the title of the UIButton for all states,
[myButton setTitle:#"Foo" forState:UIControlStateNormal];
[myButton setTitle:#"Foo" forState:UIControlStateHighlighted];
[myButton setTitle:#"Foo" forState:UIControlStateSelected];
// .. and so on
OK -- my resolution to this issue was to move the button creation to the viewDidLoad event.
I have implemented a UISegmentControl as the rightBarButton of my detailViewController.
This view controller displays that of the information passed through from a UITableView.
This UITableView's cells are populated with CoreData attribute values.
What I want to do is enable the user to go up and down in the list via the detailViewController. Instead of having to make the user have to go back to the rootViewController, they'll gain the ability to scroll through via the UISegmentControl.
I currently have this in my detailViewController.m
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// Setting up UISegmentedControl
// Segmented Control - Custom right bar button with a view
UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:
[NSArray arrayWithObjects:
[UIImage imageNamed:#"arrowdown.png"],
[UIImage imageNamed:#"arrowup.png"],
nil]];
[segmentedControl addTarget:self action:#selector(segmentAction:) forControlEvents:UIControlEventValueChanged];
segmentedControl.frame = CGRectMake(0, 0, 75, 30);
segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
segmentedControl.momentary = YES;
UIBarButtonItem *segmentBarItem = [[UIBarButtonItem alloc] initWithCustomView:segmentedControl];
[segmentedControl release];
self.navigationItem.rightBarButtonItem = segmentBarItem;
[segmentBarItem release];
}
This is then attached to the following method, for detecting the tapped control.
- (void)segmentAction:(id)sender
{
UISegmentedControl* segCtl = sender;
// the segmented control was clicked, handle it here
if([segCtl selectedSegmentIndex]==0){
NSLog(#"You clicked the down arrow - the segment clicked was %d", [segCtl selectedSegmentIndex]);
}else {
NSLog(#"You clicked the up arrow - the segment clicked was %d", [segCtl selectedSegmentIndex]);
}
}
I am also curious as to whether or not anyone knows how to detect whether or not there is anymore to go to. So say, if the note loaded is in the first position, then the down arrow is disabled, and if the note loaded is in the last position, the up arrow is disabled. Is this even possible?
Any help would be greatly appreciated.
I'd suggest you to create a formal protocol MyDataSource which provides methods for accessing the data. As a minimum, there must be a method to get number of data objects and object for a specified index.
In your DetailViewController you should have a reference to an object which conforms to MyDataSource. I'd recommend you to use instance of RootViewController as a data source for DetailViewController.
You should also keep track of index of the object that is currently displayed in DetailViewController and update UI appropriately.
When I try to pop a view controller, it doesnt update info for the previous view. Example: I have a cell that displays text in a label in View1. When you click on the cell it goes to View2 (for example) When I choose an option in View2, popViewControllerAnimated is used to go back to View1, however, I want the label to now be updated with the new option in View1.
My dilemma is that when I pop View2, the label in View1 does not update. Any ideas? I've tried adding a [view1 reloadData]; before the view pops, but no luck.
//VIEW1 the cell that displays the label.
ringLabel = [[UILabel alloc] initWithFrame: CGRectMake(25, 12.7f, 250, 20)];
ringLabel.adjustsFontSizeToFitWidth = YES;
ringLabel.textColor = [UIColor blackColor];
ringLabel.font = [UIFont systemFontOfSize:17.0];
ringLabel.backgroundColor = [UIColor clearColor];
ringLabel.textAlignment = UITextAlignmentLeft;
ringLabel.tag = 0;
ringLabel.text = [plistDict objectForKey:#"MYOPTION"];
[ringLabel setEnabled:YES];
[cell addSubview: ringLabel];
[ringLabel release];
//VIEW2 when cell clicked
CustomProfileViewController *cpvc = [CustomProfileViewController alloc];
cpvc.ringtone = [ringList objectAtIndex:indexPath.row];
[cpvc.tblCustomTable reloadData];
[self.navigationController popViewControllerAnimated:YES];
You'll want to override -viewWillAppear: on the first view controller and update the label there. (Make sure to also call super).
Example:
- (void)viewWillAppear:(BOOL)animated {
// This method is called whenever the view is going to appear onscreen.
// (this includes the first time it appears.)
ringLabel.text = [plistDict objectForKey:#"MYOPTION"];
[super viewWillAppear:animated];
}
What is your plistDict object? How you initialize it? Are you sure, that it contains right value for your #"MYOPTION" key after the second view hides? As I can see, plistDict is an object inside your first viewController. Also I cannot see any sense in the last 4 lines of your code. They cause not reloading data but memory leak.
make sure you aren't losing anything important in your dealloc method. that messed me up for weeks. i was freeing a variable that pointed to the one in my delegate.