I have an scrollview in my app.
If I click on a Button on one Page, a Subview is added. I want to remove this subview when the user scrolls the view. This function is called:
-(void) DisableViews {
[Annimation removeFromSuperview];
NSLog(#"scroll");
}
I get the NSLog many times, but the view also is Subview when i come back to the page.
I think this will happen, because the view with the subview is not the present view at this time, so i can't remove the subview.
Is there any possibility to remove a subview from any view on the subview?
edit:
ViewController.h
#interface ViewController : UIViewController {
//...
UIView *Annimation;
}
#property (nonatomic,retain) UIView *Annimation;
Implementation:
ViewController.m
#import "ViewController.h"
#import "AppDelegate.h"
#implementation ViewController
#synthesize Annimation;
//...
- (void) Bild1ButtonKlickt{
Annimation = [[UIView alloc]initWithFrame:CGRectMake(0.0, 0.0, 320.0, 480.0)];
Annimation.backgroundColor = [UIColor blackColor];
[self.view addSubview:Annimation];
}
Most likely "Annimation" (which I assume is an ivar) is nil at this point, and so nothing is happening when you try to remove it.
(As a note, don't access your ivars directly this way. Your property should be called animationView (to make it clear it's a view and not an NSAnimation, and you should access it via self.animationView. Also, methods should always have a leading lowercase. ObjC is very sensitive to method and property naming. Proper naming matters for the runtime; it's not just stylistic.)
As requested as answer: Is that the only subview in that scrollview? Anyway, one of the answers from how to remove subviews from scrollview? should work.
Now which answer from the above page did fix it?
Related
I need to push a UIView into my UINavigation controller. I am doing it by
[self.view addSubview:showContactFlow];
And on a button click in UIView I need to push another UIViewController over the UIView. From the UIView I am not able to access self.navigationcontroller How can I do this?
Edit:
I have set the UIView as the view of a new UIViewController I am pushing into, the before mentioned UIViewController . Now I would like to know, how to handle the UIView button event inside its UIViewController, in which's view it is set.
Add a UINavigationController ivar to the UIView and assign it to the main view controller's. Then you should be able to access it from the UIView.
Edit:
Your UIView subclass:
// CustomView.h
#interface CustomView: UIView {
// ...
// your variables
// ...
UINavigationController *navController;
}
#property (nonatomic, assign) UINavigationController *navController; // assign, because this class is not the owner of the controller
// custom methods
#end
// CustomView.m
#implementation Customview
// synthesize other properties
#synthesize navController;
// implementation of custom methods
// don't release the navigation controller in the dealloc method, your class doesn't own it
#end
Then before the [self.view addSubview:showContactFlow]; line just add [showContactFlow setNavController:[self navigationController]]; and then you should be able to access your hierarchy's navigation controller from your UIView and use it to push other UIViewControllers.
You should try to work with an MVC approach. So your controller has access to all that stuff and can keep pushing and popping views, so the view doesn't need to know too much about the controller.
Otherwise, and for this case you can solve it fast by using delegation. So:
showContactFlow.delegate = self;
[self.view addSubview:showContactFlow];
So later in the UIView, you can just say:
[self.delegate addSubview:self];
This is gonna work, but it's not likely to be the best approach you should use.
On button click, you can present a view controller like,
-(void)buttonFunction{
ThirdVC *third= [[ThirdVC alloc]initWithNibNme];......
[self presentViewController:third animated:NO];
}
Using Core animation you can make NavigationController's pushviewController like animation on writing code in ThirdVC's viewWillAppear: method.
where do you add the UIButton is it in showContactFlow view or in the ViewController's view??
In regard to the modalViewControllers issue the correct method is
[self presentModalViewController:viewController animated:YES];
the standard animation in upwards
I'm trying to hide the number pad, but I do not want to implement a button.
Is there a way to dismiss the number pad when the user taps outside the textfield?
This is one of those questions where you read it and say "That's easy you just..". And then you go to do it and make it super complicated. And then realize it doesn't have to be that complicated.
The answer I've come up with, and I'm sure it will help someone else, Is to use an invisible UIView that never interacts but acts on other views and maybe not in the way you'd think.
The typical answer to a question about dismissing the UIKeyboardTypeNumberPad keyboard is to add a bar that has a button as the inputAccessoryView to dismiss the keyboard. If a bar and button are undesirable generally you just listen for touch events on the background and your good to go but this question is about a tableview and that makes this much harder.
But this inputAccessoryView feature is still awesome. It allows you to define a UIView or UIView subclass to be displayed when the keyboard is shown. More importantly when the keyboard is shown due to a textfield for which it is the inputAccessoryView becoming first responder.
I could yammer on but first here is some code for a lightweight class that actually performs very well in testing.
The contents of NJ_KeyboardDismisser.h are:
#import <UIKit/UIKit.h>
// For some reason neither inputView or inputAccessoryView are IBOutlets, so we cheat.
#interface UITextField (WhyDoIHaveToDoThisApple)
#property (readwrite, retain) IBOutlet UIView *inputAccessoryView;
#end
#interface NJ_KeyboardDismisser : UIView
#property (nonatomic, weak) IBOutlet UIView *mainView;
-(id)initWithMainView:(UIView *)view; // convienience method for code
#end
And the contents of NJ_KeyboardDismisser.m are:
#import "NJ_KeyboardDismisser.h"
#implementation NJ_KeyboardDismisser {
UITapGestureRecognizer *_tapGR;
}
#synthesize mainView = _mainView;
-(void)setMainView:(UIView *)view{
if (_tapGR) [_tapGR.view removeGestureRecognizer:_tapGR];
_mainView = view;
_tapGR = [[UITapGestureRecognizer alloc] initWithTarget:_mainView action:#selector(endEditing:)];
}
-(id)initWithMainView:(UIView *)view{
if ((self = [super initWithFrame:CGRectMake(0, 0, 0, 0)])){
self.mainView = view;
}
return self;
}
-(void)didMoveToWindow{ // When the accessory view presents this delegate method will be called
[super didMoveToWindow];
if (self.window){ // If there is a window one of the textfields, for which this view is inputAccessoryView, is first responder.
[self.mainView addGestureRecognizer:_tapGR];
}
else { // If there is no window the textfield is no longer first responder
[self.mainView removeGestureRecognizer:_tapGR];
}
}
#end
You may recognize the endEditing: method, as mentioned by Cosique, it is a UIView extension method that asks a views nested textfield to resign. Sound handy? It is. By calling it on the tableview the textfield it contains resigns first responder. Since this technique works on all UIViews there is no need to artificially limit this outlet to only UITableViews so the outlet is just UIView *mainView.
The final moving part here is the UITapGestureRecognizer. We don't want to add this recognizer full time for fear of screwing up the tableview's workings. So we take advantage of UIView's delegate method didMoveToWindow. We don't really do anything with the window we just check to see if we are in one; If we are then one of our textfields is first responder, if not then it's not. We add and remove our gesture recognizer accordingly.
Okay straightforward enough, but how do you use it? Well if instantiating in code you could do it like this, in tableView:cellForRowAtIndexPath::
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Cell"];
UITextField *field = [[UITextField alloc] initWithFrame:CGRectMake(20, 6, 100, 31)];
[cell.contentView addSubview:field];
field.keyboardType = UIKeyboardTypeNumberPad;
field.inputAccessoryView = [[NJ_KeyboardDismisser alloc] initWithMainView:self.view];
}
If you are using static cells in a storyboard then the technique is different (obviously). First drag out a generic NSObject and place it in the dark grey strip below the view (where the other objects such as the view controller are). Then change this new object's class to be NJ_KeyboardDismisser. Then connect the "Keyboard Dismisser"'s mainView property to that view (generally a tableview). Then connect the inputAccessoryView property from any each text field in that scene you wish to the "Keyboard Dismisser".
Give it a try! The tableview acts normally. Apple's tap recognizer is smart enough to ignore the swipes on the table, so you can scroll. It also ignores touches in the textfields so you can edit and select other textfields. But tap outside a textfield and the keyboard is gone.
Note: This class's use is not limited to tableviews. If you want to use it on a regular view, just set the mainView property to be the same as the view controller's view.
The easiest way is to do this in your view controller:
[self.view endEditing: YES];
You can resign the responder inside the below function for your view:
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
Make sure your view is enabled for user interaction.
when creating the text field add a tag to it.
like this Yourtextfield.tag = 1;
and in you touchesEnded method
do this :
UITextField *resignTextField = (UITextField *)[self.view viewWithTag:1];
[resignTextField resignFirstResponder];
I have a simple question that I couldn't see it answered on the whole site,
One XIB file that has a UIView as the main,
in it has another UIView that's connected to one IBoutlet so I can assign it later to load a view from another XIB file. That assignment doesn't work.. it remains blank...
#interface Subclass : UIViewController {
UIView *view1;
}
#property (nonatomic,retain) IBOutlet UIView *view1;
#end
i linked view1 to the subview in the xib file
in implementation in initWithNibName I'm loading Other XIB file and use it's view and assigning it to the view1. Still this doesn't work...
detailControler = [[XibViewControler alloc] initWithNibName:#"XibViewControler" bundle:nil];
//one aproach
[self.view1 addSubview: detailControler.view];
//another aproach
[self setView1:detailControler.view];
If I'm adding the subview programaticaly to [self.view addSubview:detailControler.view] and set a frame to it, it will go fullscreen, and hide the original view.
I also had a different approach that didn't work
How to load multiple views on each button tap when using a UISegmentedVIew
This is how I usually set up a UIView inside another view, although I'm not entirely sure if it's best practice or anything like that:
if(newViewController == nil){
newViewController = [[NewViewController alloc] initWithCoder:nil];
}
newViewController.view.autoresizingMask = UIViewAutoresizingNone;
if([newViewController.view superview] == nil){
[view1 addSubview:newViewController.view];
}
Hope that Helps!
In my viewbased application i loaded oneview as mainview and another view as subview of mainview. Its work well the code snippet is ,
In mainviewcontroller,
IBOutlet UIView *subView;
#property(nonatomic,retain) UIView *subView;
#synthesize subView;
[subView release];
//add subview
[self.view addSubview:subView];
//removefromsubview
[subView removeFromSuperview];
This code works fine.....
I dont want to create subview in mainviewcontroller, so i created a new UIView class and its named as subView, now i deleted all declarations of subView from mainviewcontroller and just import subView class in mainviewcontroller. And using this [self.view addSubview:subView];
This things not work great. Can anyone help me ... How can i interact a separate UIView class with UIViewcontroller.One more thing is that UIView class have labels and textboxes can i set values from UIViewController to UIView labels and textboxes ......
Is it possible ?
Thanks in advance.......Sorry for my bad english
You have a sub-class called Subview which is declared as a UIView, i.e.
#interface Subview : UIView {
UILabel *foo;
}
#property (nonatomic, retain) UILabel *foo;
#end
Now you want to use this sub-class inside of your main UIView, which you had from the start. There are a few things you need to do.
#import the Subview in your header file, and add an instance of it to your class.
#import "Subview.h"
and inside of your #interface's {}'s,
Subview *mySubview;
In the viewDidLoad class for your main view controller, around the bottom, add something like:
mySubview = [[Subview alloc] init];
[self.view addSubview:mySubview];
[mySubview release];
First line will allocate a new "Subview" for you, second line will add this to your view so you get the stuff it has, and third line will release it. It's okay to release it here, because "self.view" will now be responsible for it, so it won't vanish.
Lastly you need to set the view up in the init method for Subview. In Subview.m, do something like:
- (id)init
{
if (self = [super init]) {
foo = [[UILabel alloc] init];
foo.text = #"Hello!";
[self addSubview:foo];
}
return self;
}
And I think that should take care of it. You also want to release foo in -dealloc for Subview but you probably know how to do that stuff already.
I'm trying to keep my code clean and keep the number of files down. I am using a UITableViewController and I would like to load another view on top of it. I thought this would be pretty simple:
(1) create an IBOutlet in my .h file
#interface MyViewController : UITableViewController {
...
UIView *downloadView;
...
}
...
#property (nonatomic, retain) IBOutlet UIView *downloadView;
...
(2) link it to my view in IB
(3) do something like:
self.view = downloadView;
or
[self.view addSubview:self.downloadView];
But that doesn't work for me. If I do
[self.tableView removeFromSuperview];
Then the table view goes away but I don't know how to add my view from my nib. I'm doing everything for tableView programatically but I didn't think that would matter. And with UITableViewController subclassing UIViewController I thought it would be no problem using addSubview or something like that. What am I missing? This shouldn't be that hard right?
Update:
So if I do the following:
UIView *newView = [[UIView alloc] initWithFrame:self.view.frame];
newView.backgroundColor = [UIColor greenColor];
[self.view addSubview:newView];
It does (mostly) what I want. So does this mean I'm messing something up with the way I'm connecting my view from IB? In IB I set the fileOwner's class to MyViewController and I make a connection between downloadView and the view that I created (in IB). That's all I should have to do right?
I think it's an issue of where in the hierarchy you're adding the view. You can try this:
[UIWindow addSubview:self.downloadView];
and see if it appears. Or perhaps,
[self.tableView addSubview:self.downloadView];
Otherwise I think you have the right idea.