I have a UIViewController that has a UITableView as a subview. I am trying to add a pull-to-refresh on the table.
Following some examples and discussions that I found here, I have the UIRefresh showing but it never calls the selector. I am not getting notified that the pull action happened.
I cannot use a UITableViewController as my main controller as I need to add a fixed button at the bottom of the screen.
I have the feeling I am missing something out that hopefully is obvious to someone else.
#interface ActivityViewController ()<UITableViewDelegate, UITableViewDataSource, UIScrollViewDelegate>
#end
- (void)viewDidLoad{
[super viewDidLoad];
_myTableView.delegate = self;
_myTableView.dataSource = self;
_tableViewController = [UITableViewController new];
_tableViewController.tableView = _myTableView;
[self addChildViewController:_tableViewController]; // Not sure this is necessary
_refreshControl = [UIRefreshControl new];
[_refreshControl addTarget:self action:#selector(loadMoreData) forControlEvents:UIControlEventValueChanged];
_tableViewController.refreshControl = _refreshControl;
}
- (void)loadMoreData{
NSLog(#"loadMoreData");
}
Ok this is now working. But I am not sure why!! I kinda left it for a bit, changed other things that needed doing and then tested once more last night and it was working. I admit I am a bit confused. I used the code below from this answer given in earlier posts here as I did a few days ago. So thank you for the time and input. It works perfect now, as expected.
// Refresh control
UITableViewController *tableViewController = [[UITableViewController alloc] init];
tableViewController.tableView = self.myTableView;
self.refreshControl = [[UIRefreshControl alloc] init];
[self.refreshControl addTarget:self action:#selector(loadMoreData) forControlEvents:UIControlEventValueChanged];
tableViewController.refreshControl = self.refreshControl;
You should instantiate your tableviewcontroller with
[UITableViewController alloc] initWithStyle:(UITableViewStyle)
using new does an alloc init but you should use a designated initializer
Related
I'm an Objective-C beginner and I've found similar answers on stackoverflow to my question, but even after trying all of the tips/advice I'm still lost.
I have an IBOutlet UIImageView, and I want it to be so that if the user swipes up or down on this Image, then the position of various images on the view controller change.
I'm very green with the UISwipegesturerecognizer coding, so please explain in a way a beginner would understand. Thank you very much in advance!!!
UPDATE:
#Axeva, I used the following code, and there are no caution warnings or errors. However, it isn't executing properly on my simulator. Here is my code :
interface math0 (){
UISwipeGestureRecognizer *swipeUp;}
- (void)viewDidLoad
{
[super viewDidLoad];
swipeUp = [[UISwipeGestureRecognizer alloc] initWithTarget: self action: #selector(swipedScreenUp:)];
[swipeUp setNumberOfTouchesRequired: 1];
[swipeUp setDirection: UISwipeGestureRecognizerDirectionUp];
[one addGestureRecognizer: swipeUp];
[swipeUp setEnabled: NO];
}
- (void)swipedScreenUp:(UISwipeGestureRecognizer*)swipeGesture {
// Sampling to see if it works
instructions.text = [NSString stringWithFormat:#"IT WORKED!"];
}
In my .h file, I declared - (void)swipedScreenUp:(UISwipeGestureRecognizer)swipeUp;. On my storyboard, I set my image (named one) so that it was accessibility and user interaction enabled.
I've also tried with [swipeUp setEnabled: YES]; in my viewDidLoad file.
Can you or anyone tell me where the error is? Thank you!!
Try something like this:
#interface YourViewController () {
UISwipeGestureRecognizer *swipeLeftToRightGesture;
}
- (void)viewDidLoad {
[super viewDidLoad];
swipeLeftToRightGesture = [[UISwipeGestureRecognizer alloc] initWithTarget: self action: #selector(swipedScreenRight:)];
[swipeLeftToRightGesture setNumberOfTouchesRequired: 1];
[swipeLeftToRightGesture setDirection: UISwipeGestureRecognizerDirectionRight];
[[self view] addGestureRecognizer: swipeLeftToRightGesture];
}
- (void)swipedScreenRight:(UISwipeGestureRecognizer*)swipeGesture {
// Move your image views as desired
}
You can adjust this basic code to do exactly what you wish. (different swipe directions; etc.)
In a controller I'm creating a UIScrollView. I'm trying to set this viewcontroller as the UISCrollview delegate and to implement the delegate's method in order to add (later) a UIPageControl.
I've read a bit, and found this link, this other link and other here on SO, and some useful tutorial all around the web, but I don't understand what I'm doing wrong. Everytime a scroll the UIScrollView, the app crashes with an EXC_BAD_ACCESS error.
Here's my .h file
#import <UIKit/UIKit.h>
#interface StatsViewController : UIViewController <UIScrollViewDelegate> {
UIScrollView *scrollView;
UIPageControl *pageControl;
}
#end
Then in my .m file, I'm creating the scrollview and trying to define the delegate method like this:
- (void)viewDidLoad {
[super viewDidLoad];
NSInteger boxWidth = self.view.frame.size.width;
NSInteger boxHeight = 412;
scrollView = [ [UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, boxHeight)];
scrollView.pagingEnabled = TRUE;
scrollView.delegate = self;
NSInteger numberOfViews = 2;
StatBreatheCounter *breatheCounter = [ [StatBreatheCounter alloc] init];
breatheCounter.view.frame = CGRectMake(0, 0, boxWidth, boxHeight);
[scrollView addSubview:breatheCounter.view];
BreatheLocationViewController *breatheLocation = [ [BreatheLocationViewController alloc] init];
breatheLocation.view.frame = CGRectMake(320, 0, boxWidth, boxHeight);
[scrollView addSubview:breatheLocation.view];
scrollView.contentSize = CGSizeMake(self.view.frame.size.width * numberOfViews, boxHeight);
[self.view addSubview:scrollView];
}
- (void)scrollViewDidScroll:(UIScrollView *)sender {
NSLog(#"RUNNING");
}
...but every time I slide on the scroll view, the app is crashing.
Now, I'm quite a n00b on Ojective-C, but I feel I'm missing something. Browsing around everything points on the fact that the delegate could be deallocated early, and when the user trigger the action, no one is handling the method (sorry for the explanation :)).
...but if the delegate it's the viewcontroller itself, how could it be deallocated?
As you can see, I'm quite confused :(
Any help would be really appreciated
--
EDIT:
I'm going to include here the solution founded thanks with your comments and answer.
When I posted my question I was so convinced that the error was coming from the way I was creating the UIScrollView and setting its delegate that I didn't realize that the problem was (as everything was suggesting, btw :)) I was allocating the StateViewController in its parent without declaring any "strong" reference to it (again, sorry for the explanation, I'm really a n00b in this).
Thanks a lot for your helping in pointing me on the right direction
It looks like you are losing reference to the delegate during scroll. I would look into any other release events around StatsViewController or other events that could cause it to be dereferenced.
At the moment I'm trying to add online multiplayer to my iOS game (that uses UIKit) using gameKit/GameCenter for matchmaking. I'm trying to present game center's matchmaker interface but with varied success. I have two view controllers (with respective .xib files), mainMenuViewController and onlineViewController, along with a file called GCHelper.h.
In CGHelper I have this:
- (void)findMatchWithMinPlayers:(int)minPlayers
maxPlayers:(int)maxPlayers
viewController:(UIViewController *)viewController
delegate:(id<GCHelperDelegate>)theDelegate
{
if (!gameCenterAvailable) return;
self.presentingViewController = viewController;
delegate = theDelegate;
[presentingViewController dismissModalViewControllerAnimated:NO];
GKMatchRequest *request = [[GKMatchRequest alloc] init];
request.minPlayers = minPlayers;
request.maxPlayers = maxPlayers;
GKMatchmakerViewController *mmvc = [[GKMatchmakerViewController alloc] initWithMatchRequest:request];
mmvc.matchmakerDelegate = self;
[presentingViewController presentModalViewController:mmvc animated:YES];
}
I use this function in my views to show the matchmaking interface. At first I tried it in mainMenuViewController, which is my first view controller using this:
[[GCHelper sharedInstance] findMatchWithMinPlayers:2 maxPlayers:2 viewController:self delegate:self];
And that worked fine but that's not where I wanted to do it, so I tried the exact same thing from onlineViewController and nothing happens, no error, just the blank view of onlineViewController.view stares back at me. I'm fairly new at this so I'm wondering if it's down to how I'm dealing with the views, here's the code I use to switch from the mainMenu to the other view:
-(IBAction)showOnlineView
{
OnlineViewController *onlineViewController = [[OnlineViewController alloc] initWithNibName:#"OnlineViewController" bundle:nil];
UIView *currentView = self.view;
UIView *theWindow = [currentView superview];
[currentView removeFromSuperview];
[theWindow addSubview:onlineViewController.view];
}
Any help would be greatly appreciated. Also, I'm not sure how I should deal with going back to the main menu if the user presses cancel (although that may become self evident once I've got this working, I just thought I'd mention it in case this lack of knowledge on my part makes it obvious I'm going about the whole thing incorrectly).
I'm still working my way around the iOS SDK and I have another probably easy one for you.
I'm getting the following error when attempting to present a popover:
CoreAnimation: ignoring exception: -[UIPopoverController initWithContentViewController: must not be called with nil.
I thought I had put in code to deal with this, although apparently not. Anyway, code is below. Any thoughts on this would be great. Cheers!
if(popoverController == nil)
{
NSLog(#"is nil");
popoverController = [[UIPopoverController alloc] initWithContentViewController:popoverDownload];
}
popoverController.delegate = self;
[popoverController presentPopoverFromRect:CGRectMake(0,0,400,200) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
UPDATE
I guess I'm not initialising popoverDownload correctly/at all.
In my .h file
PopoverDownloadViewController *popoverDownload;
#property (nonatomic,retain) PopoverDownloadViewController *popoverDownload;
UPDATE WITH ANSWER
And it was as easy as...
PopoverDownloadViewController *popoverDownload = [[PopoverDownloadViewController alloc] init];
Just to mark this answer closed. I needed to initialise the popover using the following code...
PopoverDownloadViewController *popoverDownload = [[PopoverDownloadViewController alloc] init];
Thanks to omz for the hints in the right direction.
I'm trying to do very simple example of a UINavigationController. Here is my code:
- (void)viewDidLoad {
[super viewDidLoad];
This next line works, or at least doesn't blow up.
navController = [[UINavigationController alloc] initWithRootViewController:self];
self.title = #"blah";
PageOneController *one = [[[PageOneController alloc]init] autorelease];
Example 1. THIS LINE DOES NOTHING
[navController pushViewController:one animated:NO];
Example 2. THIS LINE WORKS (but no nav controller, of course)
[self.view addSubview:one.view];
}
Why am I unable to push ViewController instances onto the navController and see the screen change?
Note: I realize that I might have my concepts backwards and I don't need to have my view referencing a UINavigationController... or something.
- (void)viewDidLoad {
[super viewDidLoad];
PageOneController *one = [[[PageOneController alloc]init] autorelease];
one.title = #"blah";
navController = [[UINavigationController alloc] initWithRootViewController:one];
[self.view addSubview:navController.view];
}
The basic idea behind it is that a navigation controller's root view controller is the controller which view will be displayed first in the navigation controller hierarchy. The root controller is not the view controller that you plug the navigation controller into. Hope this helps.
I'm just restating #E-ploko's answer, which is 100% correct (which is why I marked it best answer).
You need more views (and view controllers) to use the UINavigationController. One of them houses the UINavigationController, and its rootViewController is the first page of the series (the one that has no "back").
I got rid of the external dependencies for the code sample: obviously this is monolithic sample code, not monolithic real code.
- (void)viewDidLoad {
[super viewDidLoad];
UIViewController *one = [[UIViewController alloc] init];
[one.view setBackgroundColor:[UIColor yellowColor]];
[one setTitle:#"One"];
navController = [[UINavigationController alloc] initWithRootViewController:one];
// here 's the key to the whole thing: we're adding the navController's view to the
// self.view, NOT the one.view! So one would be the home page of the app (or something)
[self.view addSubview:navController.view];
// one gets reassigned. Not my clearest example ;)
one = [[UIViewController alloc] init];
[one.view setBackgroundColor:[UIColor blueColor]];
[one setTitle:#"Two"];
// subsequent views get pushed, pulled, prodded, etc.
[navController pushViewController:one animated:YES];
}