Adding new view into another subview - objective-c

I am learning iOS. I m using Xcode 4.3.2 , and i have created a button, and in the callback, i have used the following code.
1) Created single view application
2) creating a new view -> newV
3) creating a button but;
4) adding but as a subview of newV.
5) adding newV as a subview of main view.
-(IBAction) submitButtonPressed:(id)sender
{
NSLog (#" Submit Button is pressed ");
UIView *newV = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
newV.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
UIButton *but = [[UIButton alloc] init];
[but setTitle:#"SubView" forState:UIControlStateNormal];
[newV addSubview:but];
[self.view addSubview:newV];
}
But the problem i get is, only the view viewV is shown, but button is not shown. How to resolve this issue ?

When you created the button, you didn't provide a frame. Try using:
UIButton* but = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, buttonWidth, buttonHeight)];
When you created the button, it was of zero size, so you couldn't see it.

Try adding the button after adding in the view newV.

Related

How to make a UIActivityIndicatorView in a UIToolbar tappable

I'm using this code to insert an UIActivityIndicatorView to my toolbar
-(void)addActivityIndicatorToToolbar {
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
activityIndicator.userInteractionEnabled = YES;
activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhite;
[activityIndicator startAnimating];
UIBarButtonItem *barButton = [[UIBarButtonItem alloc] initWithCustomView:activityIndicator];
barButton.target = self;
barButton.action = #selector(playButtonPressed:);
NSMutableArray *toolbarItemsMutable = [self.toolbar.items mutableCopy];
[toolbarItemsMutable replaceObjectAtIndex:0 withObject:barButton];
self.toolbar.items = toolbarItemsMutable;
}
However, when I tap the UIActivityIndicatorView the action (playButtonPressed) is not performed.
How can I correct this?
It seems more likely that you want a button with an activity indicator inside it. You can do this by creating a button with a custom view as described in this post. Then you can set the action of this button as normal, and you'll probably want to retain a reference to the activity indicator to start and stop it.
I ended up implementing a poor man's solution by adding an extra view on top of the activityIndicatorView with a gestureRecognizer.
This is a quite old question but why don't you directly add a UITapGestureRecognizer instance to your UIActivityIndicatorView instance ? (works fine on iOS 8.2, I didn't test yet on previous versions).

Detecting background tap

I'm busy with an app you need to touch a button, but when u touch outside the button (on the background of the app screen) i want to display an alert.
Does anyone know how to detect an tap on the background
Button:
MyButton = [UIButton buttonWithType:UIButtonTypeCustom];
MyButton.frame = CGRectMake(0, 0, 100, 100);
[MyButton setImage:[UIImage imageNamed:#"tap.png"] forState:nil];
[self.view addSubview:MyButton];
[MyButton addTarget:self action:#selector(buttonPressed) forControlEvents:UIControlEventTouchUpInside];
You could add a gesture recogniser to the view.
E.g.
// in viewDidLoad:
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(backgroundTapped:)];
tapRecognizer.numberOfTapsRequired = 1;
[self.view addGestureRecognizer:tapRecognizer];
- (void)backgroundTapped:(UITapGestureRecognizer*)recognizer {
// display alert
}
What you could also try is having a full size UIView behind the button that has a gesture recogniser on it:
// in viewDidLoad:
UIView *backgroundView = [[UIView alloc] initWithFrame:self.view.bounds];
backgroundView.backgroundColor = [UIColor clearColor];
backgroundView.opaque = NO;
[self.view addSubview:backgroundView];
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(backgroundTapped:)];
tapRecognizer.numberOfTapsRequired = 1;
[backgroundView addGestureRecognizer:tapRecognizer];
- (void)backgroundTapped:(UITapGestureRecognizer*)recognizer {
// display alert
}
This might work better than adding the gesture recogniser to self.view.
You can create a custom subclass of a UIView, make it transparent but with touch handlers, and place a full size instance of that new view subclass underneath your button. You can then have that subview send a message to your main view controller (via delegation) whenever it see a touch down event. Since the button is on top of this subview, the subview won't do anything if the button is tapped.
I looked at the solution in the first answer and tested it. It did not work for me. The gesture recognizer captured my button & other UI element touches (I'm loading from nib)
A window delivers touch events to a gesture recognizer before it delivers
them to the hit-tested view attached to the gesture recognizer. Generally,
if a gesture recognizer analyzes the stream of touches in a multi-touch
sequence and does not recognize its gesture, the view receives the full
complement of touches
I used a slightly different solution:
UIButton *invisibleBtn = [[UIButton alloc] initWithFrame:self.view.bounds];
invisibleBtn.titleLabel.text = #"";
invisibleBtn.backgroundColor = [UIColor clearColor]; // no tap events if this is not set, bizarre
[invisibleBtn addTarget:self action:#selector(backgroundTapped:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:invisibleBtn];
[self.view sendSubviewToBack:invisibleBtn];

Custom navbar titleView won't clear previous titles before loading new ones

So I created a custom UINavigationItem category to be able to make a custom titleview for my navbar, but everytime I push/pop a view, it simply adds the new title without getting rid of the old one causing the title to just be a jumble of letters. Here's the relevant code:
#implementation UINavigationItem (CustomNavigationItem)
-(UIView *)titleView
{
[self setTitleView:nil];
UILabel *newTitleView = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 220, 32)];
newTitleView.center = CGPointMake(160, 22);
newTitleView.backgroundColor = [UIColor clearColor];
newTitleView.textColor = [UIColor whiteColor];
newTitleView.textAlignment = UITextAlignmentCenter;
newTitleView.text = self.title;
newTitleView.textAlignment = UITextAlignmentCenter;
return newTitleView;
}
#end
You have to remove the old uilabel from its superview, by setting to nil it doesn't do that. That's why you are messing the letters on screen. I also do not think you are getting a recursion, because you are caling the setter, but I maybe wrong.
A quick thing you could is to assign a tag to your newest created view.
[[self.view viewWithTag:YourCustomEnumTag] removeFromSuperView];
// create your view....
textView.tag=YourEnumCustomTag;

UINavigationBar custom title being hidden by background

I am adding a custom UIImageView to my UINavigationBar using this code:
UIImageView *background = [[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)] autorelease];
[background setImage:[UIImage imageNamed:#"nav_background.png"]];
[background setTag:kTagForReference];
[self.navigationController.navigationBar insertSubview:background atIndex:0];
I then add a custom title using this code:
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 400, 44)];
...
[self.navigationItem setTitleView:label];
[label release];
But on some of my pushed views the title is being hidden (or isn't visible). I can't seem to push more than two views onto the stack without the title disappearing.
I've tried to force my UIImageView background to the back of the bar but that still doesn't help. I've printed the subviews of the UINavigationBar and I can see that the UILabel is there, I just can't see it!
Any help would be greatly appreciated.
If you can run the dumpWindows() function, the output would show the view hierarchy so you can see what view is covering it up.
You most likely want to use a UIToolBar instead of a NavigationBar. Then you can add the subviews to the UIToolbar.
Bring the UILabel to the front most view.
[self.view bringSubviewToFront: label];

How to avoid corrupted borders when presenting a modal controller in a UIPopOverController

I'm having an issue when presenting a modal view controller within a popover using the modal presentation style UIModalPresentationCurrentContext.
Something strange is happening to the border of the popover, here are some before/after screenshots:
Before presenting the modal controller:
And now once the modal controller has been displayed:
See how the border width on the left and top has changed? When the modal controller is dismissed the border width stays corrupted but if the whole popover is dismissed it displays correctly until the modal controller is shown again.
Here is the code we're using in a sample project that we've created to demonstrate the problem:
- (IBAction)showModalViewButtonTapped:(id)sender
{
UIViewController *viewController = [[UIViewController alloc] init];
UIButton *dismissButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
dismissButton.frame = CGRectMake(30, 30, 100, 25);
[dismissButton setTitle:#"Dismiss" forState:UIControlStateNormal];
[dismissButton addTarget:self action:#selector(dismissButtonTapped) forControlEvents:UIControlEventTouchUpInside];
[viewController.view addSubview:dismissButton];
viewController.view.backgroundColor = [UIColor redColor];
viewController.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentModalViewController:viewController animated:YES];
[viewController release];
}
Has anyone seen this before? any ideas?