Please help! It seems to simple, but, sorry, I 'have' to ask, as it's not working. I have a main view with a UITableView. On swiping, am adding a subview which has a picker and a button. It works fine: I swipe & the subview appears in front of the main view, but when I click the picker or the button, nothing really happens in the subview; instead the components in the main view (which is beneath the subview) get called! Am saying this for sure, because, in the main view, I have a picture beneath the added-subview (tapping the picture opens a new view). Now, when I tap the picker in the subview (the picture is beneath it in the main view), the picture gets tapped & the new view opens up! How is this possible?
This is the subview (in Interface Builder)
Here's my code snippet:
In my MainViewController.m (viewCtrlrFilter is the subview added when the user swipes in the main view)):
....
self.viewCtrlrFilter = (ViewController_Filter *) [myStoryboard instantiateViewControllerWithIdentifier:kNameViewCtrlrFilter];
...
// This is called when the user pans/swipes
// This does work fine; the subview gets added & is visible
[self.viewCtrlrFilter initializeView];
[self.viewCtrlr.view setFrame:CGRectMake(310.0, 220.0, 243.0, 208.0)];
[self.view addSubview:self.viewCtrlrFilter.view];
...
From ViewController_Filter.h :
...
// This implements the Picker Delegate & DataSource
// which I have wired to the picker in IB
#interface ViewController_FilterPhotographers : UIViewController <UIPickerViewDelegate, UIPickerViewDataSource>
...
// This is called when the button in the subview
// (screenshot above) is pressed
// It's wired through the IB
-(IBAction) buttonPressed:(id) sender;
...
From ViewController_Filter.m :
-(void) initializeView {
self.myPicker.delegate = self;
self.myPicker.dataSource = self;
self.myPicker.showsSelectionIndicator = YES;
CGRect rect = self.myPicker.frame;
rect.origin = CGPointMake(0.0, 0.0);
self.myPicker.frame = rect;
self.myPicker.transform = CGAffineTransformMakeScale(0.625,0.625);
[self.myPicker becomeFirstResponder];
}
...
-(IBAction) buttonPressed:(id) sender {
NSLog(#"hi");
}
...
- (void)viewDidLoad
{
[super viewDidLoad];
[self initializeView];
}
...
When the user swipes, the subview does get added (the picker & button are seen), but when I click the button, the IBAction method isn't getting called. Instead, funnily, the component in the main view (beneath the subview) is getting called!
It works now! Looks like setting the datasource & delegate for the picker view from both the code & IB was a problem. I set it from IB & removed it from code. It works fine now!
Related
I am using a UIView item on my view controller that contains a picker view and a button, which needs to appear on the screen only when the show button is clicked.
I created a outlet for my UIView with name *pickerView
The default position of this view (on the right properties bar of Xcode) is (0,200,320,261) for (x,y, height and width) which basically makes it appear at the base of the ViewController.
What I did for this view to hide initially when the view controller loads is, in the ViewDidLoad method I put this code:
pickerView.frame=CGRectMake(0,450,320,261);
For the action of show button,
pickerView.frame=CGRectMake(0,200,320,261);
I have a hide button inside this UIView, in its action i have
pickerView.frame=CGRectMake(0,450,320,261);
SO, from what I expect when I run the application, the UIView pickerView should initially hide because of code in viewDidLoad, and show button should bring it on the screen.
My problem is show and hide button works fine, but every time I load this ViewController the View appears on screen by default. Help me hide this UIView when I load the viewController.
Simpley don't set the frame for picker view
i am posting a sample code it makes picker view hide and appear when tapping the button
i am using the property "hide"
hear is the sample code
- (void)viewDidLoad
{
[super viewDidLoad // Do any additional setup after loading the view, typically from a nib.
//as simple dont set frame.
// i am using xib from there i wired up picker view
self.myPickerView.hidden = YES; //just hide it whenever you dont use it.
}
- (IBAction)whenShowHideButtonTapped:(id)sender
{
//when button pressed just show it
if(self.myPickerView.hidden)
{
self.myPickerView.hidden = NO;
}
else
{
self.myPickerView.hidden = YES;
}
}
hope this helps .. :)
You could call the hide code in 'viewWillAppear:' like this:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self hidePicker];
}
I have created a new project in XCode and used the new Storyboard-feature to create two different View Controllers.
The first View Controller is attached to the main files (ViewController.h, Viewcontroller.m). The second View Controller is attached to it's own set of .h/.m files (NewUserController.m/.h)
Now for the problem which I havent been able to find a solution for in the last hours;
I have added a button the second view controller and attached the button to an IBAction (verifyNumber). When I attach the 'Touched Up Inside' event the IBAction is never fired. However, when I attach the 'Touch Down' everything works fine..
Both View Controller's have got the 'user interaction enabled' selected and apart from the button the second view controller doesn't contain any other elements. Also, my manual performSegueWithIdentifier is working (switch from view1 to view2).
Can anyone spot where it has gone wrong?
The code:
ViewController.m
- (void)firstStartup {
// Future use for getting userID
// Switch to loginview
[self performSegueWithIdentifier:#"segueLogin" sender:self];
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// Fire firstStartup
[self firstStartup];
}
NewUserController.h
#import <UIKit/UIKit.h>
#interface NewUserController : UIViewController
#property (weak, nonatomic) IBOutlet UITextField *inputNumber;
- (IBAction)backgroundTap;
//- (IBAction)verifyNumber;
- (IBAction)verifyNumber:(id)sender;
#end
NewUserController.m
#import "NewUserController.h"
#implementation NewUserController
#synthesize inputNumber;
// Collect User data & Start Request
- (IBAction)verifyNumber:(id)sender; {
inputNumber.text = #"testing";
}
- (IBAction)backgroundTap {
[inputNumber resignFirstResponder];
}
UPDATE
Because of the response of NJones I have tested some more and deleted the gesturerecognizer I had present on the second view. After deleting this recognizer the UIButton works with all events (Touched Up Inside).
Does the recognizer somehow block any 'tap' events to overlaying objects (such as the UIButton)?
I have a few thoughts,
1) Why do you have:
- (IBAction)backgroundTap;
//- (IBAction)verifyNumber;
- (IBAction)verifyNumber:(id)sender;
There is a difference between verifyNumber and verifyNumber:(id)sender and they can both exist at the same time, and both can be connected in the nib.
2) Are you using any UIGestureRecoginzers on the view at all?
3) Is this button a custom button or subclass of UIButton?
4) (I truly don't think this will help solve your problem it's just good practice, and I'm already typing :)) Using a view property to check if a method was called is inconclusive at best. Try putting a log statement in the IBAction method like So:
- (IBAction)verifyNumber:(id)sender; {
NSLog(#"verifyNumber:");
inputNumber.text = #"testing";
}
I'd like to re-create the large popover we have in the mail app, in portrait mode, since iOS5.
You swipe from the left part of the screen and the rootView appears in a list-type popover.
Is it a private API ? I can't even find any documentation about it.
Thanks a lot for your help !
The only way I've been able to do this is to use a UISplitViewController. Put the view which you want to occupy your entire window as your detail view, and the view within the "large" popover as the master.
The idea is to always have your master coming from the popover, instead of being docked on the side as it is by default in iOS5
After you've done the storyboard work above, make the detailViewController your splitViewControllerDelegate
- (void)viewDidLoad
{
[super viewDidLoad];
self.splitViewController.delegate = self;
}
Lastly, implement the following UISplitViewControllerDelegate methods in the detailViewController
- (BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController:(UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation
{
//This ALWAYS hides the masterVC (in your case the rootVC) regardless of device orientation
return YES;
}
- (void)splitViewController:(UISplitViewController *)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)pc
{
// Assuming your detailViewController has a UIToolbar mapped to the .toolbar property
// This takes the barButtonItem from which your masterViewController "pops over"
// and places it in your UIToolbar
self.toolbar.items = [NSArray arrayWithObject:barButtonItem];
}
I downloaded iAdSuite and looked into ADBannerNavigation.
Inside, I changed the RootViewController to subclass TextViewController in order to take advantage of the iAd banner resizing. I want to display ads on the RootView as well.
This is now RootViewController.h:
#import <UIKit/UIKit.h>
#import "TextViewController.h"
#interface RootViewController : TextViewController
#end
Everything else is the same. When I compile and run, no ads show up in RootView, and when I click into TextView, ads suddenly show up.
When I click to go back, there is now white space in RootView.
WHY?
How do you remove the white space?
Found the error in how I was removing the ADBannerView.
iAd Suite tells us to:
Note: If your application has multiple tabs or views displaying an iAd banner, be sure to share a single instance of ADBannerView across each view. Then, before your users navigate to a new view, set the shared instance’s delegate property to nil, remove it from the old view hierarchy, then add the same instance to the opening view and set its delegate to the appropriate view controller. The "AdBannerNavigation" sample shows this technique.
So, in my iADBannerView.m, I have:
- (void)viewWillDisappear:(BOOL)animated{
[self removeADBannerFromView];
[super viewWillDisappear:animated];
}
- (void)removeADBannerFromView{
NSLog(#"ad removed from view");
ADBannerView *adBanner = SharedAdBannerView;
adBanner.delegate = nil;
[adBanner removeFromSuperview];
}
- (void)dealloc{
// we are being called here when we navigate away from this view controller,
// so go ahead and reset our AdBannerView for the next time
//
ADBannerView *adBanner = SharedAdBannerView;
adBanner.delegate = nil;
[adBanner removeFromSuperview];
[contentView release]; contentView = nil;
[super dealloc];
}
By setting breakpoints, I saw that by exiting a view, viewWillDisappear was being called on view1, then viewWillAppear on view0 and then dealloc on view1.
The problem was that view1 already removed the ADBannerView from the view, so [adBanner removeFromSuperView] was removing the Ad from view0.
Problem solved by removing offending code from the dealloc method.
I have seen the post for How to switch views by buttons on iPhone? but this doesn't answer how to switch back and forth between views with buttons. The person that asked the question settled on the answer that they could switch between views with uinavigationcontroller.
I put the following code in an ibaction that kicks off when a button is pressed in the primary view.
PhoneNumberViewController *phoneNumberViewController1 = [[PhoneNumberViewController alloc] initWithNibName:#"PhoneNumberView2" bundle:nil];
self.phoneNumberViewController = phoneNumberViewController1;
[self.view removeFromSuperview];
[self.view insertSubview: phoneNumberViewController1.view atIndex:0];
When this code executes the whole view just goes blank. If I omit the removefromsuperview portion then the view disappears behind my button but the button still remains. I'm not sure if this is the right way to switch between buttons but if anyone knows how to do this please help. Also if anyone knows about any example projects that switch between views with buttons let me know.
Thanks a million!
You removed the view controller's view from it's superview and then added a subview to it. The view hierarchy is broken at the view controller's superview (likely your window). That is why you are getting a blank screen.
You'd likely want to keep a reference around to the original view and then swap it out to the new view by setting the view controller's view to the new view.
// origView is an instance variable/IBOutlet to your original view.
- (IBAction)switchToPhoneView:(id)sender {
if (origView == nil)
origView = self.view;
self.view = phoneViewController.view;
}
- (IBAction)switchToOriginalView:(id)sender {
self.view = origView;
}
The technique I usually use involves creating a superview class which contains a toolbar at the bottom, and a content view UIView class filling the rest of the screen.
I then add subviews to the content view to change the views based on button clicks. This approach makes it so the toolbar on the same is constant across all views. I start by defining a helper function like this:
-(void) clearContentView {
//helper to clear content view
for (UIView *view in [self.contentView subviews]){
[view removeFromSuperview];
}
}
My IBAction then looks like this:
-(IBAction) buttonClicked{
self.title = #"Images"; //change title of view
[self clearContentView]; //clear content view
[self.contentView addSubview:self.imagesViewController.view]; //add new view
[self.imagesViewController viewWillAppear:YES]; //make sure new view is updated
[self enableButtons]; //enable all other buttons on toolbar
self.imagesButton.enabled = NO; //disable currently selected button
}