iOS Bounds of UIView in ViewDidLoad - ios

I wanted to use the bounds of a UIView to create a UILabel and add it to that UIView inside the viewDidLoad method, however, I have found that the bounds of UIView is still null inside viewDidLoad. But when I look at a demo app, the bounds of its UIView is already initialised in viewDidLoad.
In the interface I have
#interface ViewController : UIViewController
#property (weak, nonatomic) IBOutlet UIView *promotionView;
#end
And I am trying to do
- (void)viewDidLoad
{
[super viewDidLoad];
UIView *container = [[UIView alloc] initWithFrame:self.promotionView.bounds];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, container.bounds.size.height-100, 320, 20)];
label.text = #"Promotion Title";
[container addSubview:label];
[self.promotionView addSubview: container];
}
but it doesn't work because the bounds of promotionView is null.

You can do it like this in viewDidAppear:
-(void)viewDidAppear:(BOOL)animated {
static int first = 1;
if (first) {
UIView *container = [[UIView alloc] initWithFrame:self.promotionView.bounds];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, container.bounds.size.height-100, 320, 20)];
label.text = #"Promotion Title";
[container addSubview:label];
[self.promotionView addSubview: container];
first = 0;
}
}

Related

Button creates at tableFooterView not response to events

I create a tableView in a class inherit from UIView.It works well when I add a button at tableFooterView on this tableView.
CustomView.h
#import <UIKit/UIKit.h>
#interface CustomView : UIView<UITableViewDelegate,UITableViewDataSource>
#end
CustomView.m
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{
UIView * customView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width, 80)];
UIButton * tempButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 100, 40)];
tempButton.center = customView.center;
tempButton.backgroundColor = [UIColor redColor];
[tempButton addTarget:self action:#selector(doButtonAction) forControlEvents:UIControlEventTouchUpInside];
[customView addSubview:tempButton];
return customView;
}
- (void)doButtonAction{
NSLog(#"123");
}
NSLog:123
However,I public this button and make a target-action in my controller.It response nothing.
CustomView.h
#property (strong, nonatomic) UIButton * tempButton;
CustomView.m
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{
UIView * customView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width, 80)];
self.tempButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 100, 40)];
self.tempButton.center = customView.center;
[customView addSubview:self.tempButton];
return customView;
}
ViewController.h
- (void)viewDidLoad {
[super viewDidLoad];
CustomView *cv = [[CustomView alloc] initWithFrame:self.view.bounds ];
[cv.tempButton addTarget:self action:#selector(doButtonAction) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:cv];
}
- (void)doButtonAction{
NSLog(#"123");
}
what did I miss?
In the viewdidload you are not set any thing on the button,
You just assign in the #interface.
but you must be alloc and set the frame and backgroundcolor and all properties on the button in the viewdidload .
After that it will work.
May be it will help you or feel free.

addSubview is not displayed UIView

I described [self.view addSubView:myView];,
but, myView is not displaying self.view.
ViewController.h
#interface ViewController : UIViewController{
UIView *myView;
}
#property (nonatomic, strong) UIView *myView;
ViewController.m
#synthesize myView;
- (void)viewDidLoad
{
[super viewDidLoad];
myView.frame = CGRectMake(-10, 70, 320, 480);
[self.view addSubview:myView];
myView.backgroundColor = [UIColor redColor];
[self.view bringSubviewToFront:myView];
}
Do you have any solutions?
You need to allocate your view first:
- (void)viewDidLoad
{
[super viewDidLoad];
// If you use custom view change UIView to the custom class name
myView = [[UIView alloc] initWithFrame:CGRectMake(-10, 70, 320, 480)];
[self.view addSubview:myView];
myView.backgroundColor = [UIColor redColor];
[self.view bringSubviewToFront:myView];
}

Remove previous UIView before creating another on

I have a method were I'm creating UIView and it works fine when I call it from IBAction. But when I call the same method again it draws another view on top and I believe it's a memory leak. How do I remove previous UIView before creating another one? Thanks!
- (int)showQuestionMethod:(int)number;
{
UIView *questionView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 250)];
questionView.backgroundColor = [[UIColor alloc] initWithRed:0.93 green:0.93
blue:0.93 alpha:1.0];
[self.view addSubview:questionView];
questionView.tag = questionNumber;
UILabel *questionLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 20, 280, 0)];
questionLabel.text = question1;
[questionView addSubview:questionLabel];
CGRect frame = questionView.frame;
frame.size.height = questionHeight;
questionView.frame = frame;
questionView.tag = questionNumber;
return currentQuestion;
}
- (IBAction)nextQuestion:(id)sender {
[self showQuestionMethod:questionNumber];
}
Create a property which will let you reference a view:
#property(nonatomic, strong) UIView *questionView;
Then change your method to remove the old view and create a new one:
- (int)showQuestionMethod:(int)number;
{
// Remove the previous view.
[_questionView removeFromSuperview];
// Create a new view.
_questionView= [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 250)];
_questionView.backgroundColor = [[UIColor alloc] initWithRed:0.93 green:0.93
blue:0.93 alpha:1.0];
// Add the view.
[self.view addSubview:_questionView];
_questionView.tag = questionNumber;
UILabel *questionLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 20, 280, 0)];
questionLabel.text = question1;
[_questionView addSubview:questionLabel];
CGRect frame = _questionView.frame;
frame.size.height = questionHeight;
_questionView.frame = frame;
_questionView.tag = questionNumber;
return currentQuestion;
}
The simplest way would be to keep a reference to the view you will want to remove (a private property would work nicely). You could add the code at bottom to the top of your controllers .m file:
#interface MyUIViewController ()
#property (nonatomic, strong) UIView* questionView;
#end
Then modify your method as follows:
- (int)showQuestionMethod:(int)number;
{
[self.questionView removeFromSuperview]
self.questionView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 250)];
self.questionView.backgroundColor = [[UIColor alloc] initWithRed:0.93 green:0.93
blue:0.93 alpha:1.0];
[self.view addSubview:self.questionView];
self.questionView.tag = questionNumber;
UILabel *questionLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 20, 280, 0)];
self.questionLabel.text = question1;
[self.questionView addSubview:questionLabel];
CGRect frame = questionView.frame;
frame.size.height = questionHeight;
self.questionView.frame = frame;
self.questionView.tag = questionNumber;
return currentQuestion;
}
use this before creating new view
[myview removeFromSuperview];
You can either keep a reference to the view by adding #property (strong, nonatomic) UIView *questionView; in your #interface declaration then call [_questionView removeFromSuperview]; to remove it.
Or, better yet, keep that reference to it then have a method to reload the info on it and animate it out/back into view (perhaps by fading out, reloading the data on it, then fading it back in). That way you aren't throwing away / recreating views all the time, and instead you're just reusing the same, already created view.
[self.questionView removeFromSuperview];
before adding the other view, remove this from the superview!
Why not reuse the view?
If you'd rather delete it every time and you don't want to keep a reference to it, you can always set (dirty but simple):
questionView.tag = SOME_CONST;
And then add in the beginning of your method:
[[self.view viewWithTag:SOME_CONST] removeFromSuperview];
I know this question has been answered, but i want to add a precaution that you before removing a UIView or anything else you should FIRST CHECK IF IT IS ALLOCATED. So the removal should be like:
// Make property first
#property (nonatomic, strong) UIView *questionView;
- (int)showQuestionMethod:(int)number;
{
// Check it it is allocated
if(questionView)
{
[questionView removeFromSuperView];
//[questionView release]; // Un-Comment it if NOT using ARC
questionView = nil;
}
// At this point you safe to create a new UIView.
questionView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 250)];
questionView.backgroundColor = [[UIColor alloc] initWithRed:0.93 green:0.93
blue:0.93 alpha:1.0];
[self.view addSubview:questionView];
questionView.tag = questionNumber;
UILabel *questionLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 20, 280, 0)];
questionLabel.text = question1;
[questionView addSubview:questionLabel];
CGRect frame = questionView.frame;
frame.size.height = questionHeight;
questionView.frame = frame;
questionView.tag = questionNumber;
return currentQuestion;
}
Hope the snippet and comment inside makes sense.
Happy Coding!!!

View has wrong frame when loaded from xib and shown first time

I created a view to show in MapView annotation callout.
If I didn't use xib and instantiate this view with initWithFrame, then there is no problem.
But if I use xib, size shown on map is bigger, than is should be.
Code in view:
#interface CalloutContentView : UIView
#property (nonatomic) Visit *visit;
+ (id)customView;
#end
#import "CalloutContentView.h"
#interface CalloutContentView ()
#property (weak, nonatomic) IBOutlet UILabel *title;
#property (weak, nonatomic) IBOutlet UILabel *subtitle;
#property (weak, nonatomic) IBOutlet UISegmentedControl *sc;
#end
#implementation CalloutContentView
+ (id)customView
{
CalloutContentView *customView = [[[NSBundle mainBundle] loadNibNamed:#"CalloutContentView" owner:self options:nil] lastObject];
if ([customView isKindOfClass:[CalloutContentView class]])
return customView;
else
return nil;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// _title = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, w, 18)];
_title.font = [UIFont boldSystemFontOfSize:15.0];
// _title.textAlignment = NSTextAlignmentLeft;
_title.textColor = [UIColor colorWithWhite:0.199 alpha:1.000];
_title.numberOfLines = 1;
_title.backgroundColor = [UIColor yellowColor];
[self addSubview:_title];
// _subtitle = [[UILabel alloc] initWithFrame:CGRectMake(0, 25.0, w, 14)];
_subtitle.font = [UIFont systemFontOfSize:12.0];
_subtitle.textAlignment = NSTextAlignmentLeft;
_subtitle.textColor = [UIColor colorWithWhite:0.239 alpha:1.000];
_subtitle.backgroundColor = [UIColor clearColor];
[self addSubview:_subtitle];
// _sc = [[UISegmentedControl alloc]initWithItems:#[#"One",#"Two"]];
_sc.frame = CGRectMake(0, self.frame.size.height - 30, w, 30);
[_sc addTarget:self action:#selector(segmentedControlValueDidChange:) forControlEvents:UIControlEventValueChanged];
[self addSubview:_sc];
}
return self;
}
# end
And in MapViewController:
- (void)popupMapCalloutView {
// Change this for creating your Callout View
CalloutContentView *customView = [CalloutContentView customView];
// CalloutContentView *customView = [[CalloutContentView alloc]initWithFrame: CGRectMake(0, 0, 10, 90)];
// if you provide a custom view for the callout content, the title and subtitle will not be displayed
_calloutView.contentView = customView;
VisitAnnotationView *bottomPin = _visitAnnotationViews[_idAnn];
bottomPin.calloutView = _calloutView;
[_calloutView presentCalloutFromRect:bottomPin.bounds
inView:bottomPin
constrainedToView:_mapView
permittedArrowDirections:SMCalloutArrowDirectionAny
animated:YES];
}
That's how it look like when xib is used:

UIScrollView not showing iOS7

I'm try to add a scrollview totally by code to a modal view, but it doesn't show.
I've tried different ways but I can't see the mistake,
Somebody could help me?
here my code:
#interface AddWithScrollOrizontal ()<UIScrollViewDelegate>{
//IBOutlet UIScrollView*scroll;
}
#property (strong, nonatomic) UIScrollView*scroll;
#implementation AddWithScrollOrizontal
#synthesize scroll;
- (void)viewDidLoad
{
self.scroll = [[UIScrollView alloc]init];
self.scroll.delegate = self;
if (IS_IPHONE_5) {
self.scroll.frame = CGRectMake(0, 58, 320, 270);
}else{
self.scroll.frame = CGRectMake(0, 20, 320, 270);
}
self.scroll.backgroundColor = [UIColor redColor];
self.scroll.pagingEnabled = YES;
self.scroll.contentSize =CGSizeMake(1280, 270);
UIView*firstView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 270)];
...
UIView*fourthView = [[UIView alloc]initWithFrame:CGRectMake(960, 0, 320, 270)];
[self.scroll addSubview:firstView];
[self.scroll addSubview:secondView];
[self.scroll addSubview:thirdView];
[self.scroll addSubview:fourthView];
[self.view addSubview:self.scroll];
}
You say you're adding it totally by code, but you're making an IBOutlet to scroll. Did you create it in IB? If not, your problem is that you never instantiate the scroll view. Also, there's no need to create an ivar for scroll, just create the property inside the #interface declaration for your class extension, and refer to it with self.scroll.

Resources