Subclass viewController in storyboard and programmatically change UI from subclass - ios

What I'm basically trying to do is have a storyboard with a navController and a couple views which are set up programmatically - or at least have subviews that are added programatically. So I've set up an example workspace, I have a navController and 2 viewControllers that are pushed depending on which button is pressed.
Here's the storyboard:
As you can see, the viewController on the bottom has it's class set to CVViewController. In CVViewController, I have my viewDidLoad as
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIView *redColor = [[UIView alloc] initWithFrame:self.view.window.frame];
redColor.backgroundColor = [UIColor redColor];
[self.view addSubview:redColor];
}
But then when I segue into this view on the simulator, there's no red background that should be there (because I added it programmatically).
So I'm not sure where I'm going wrong. I basically just want to be a able to configure a storyboard viewController programmatically from a custom class

Change this:
UIView *redColor = [[UIView alloc] initWithFrame:self.view.window.frame];
to this:
UIView *redColor = [[UIView alloc] initWithFrame:CGRectMake(0,0,self.view.frame.size.width, self.view.frame.size.height)];

Related

Issue with presenting an external UIView in a UIViewController: outlets don't show up

I have a UIViewController that has its UI elements setup in storyboard, and things are showing up fine. Now I created a new UIView in separate xib, .h and .m files, I'll call it "overlay"; then I present that overlay which should cover everything below, so that only the overlay can be seen:
// in controller.m
OverlayView *overlayView = [[OverlayView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
overlayView.layer.zPosition = 1000;
[self.view addSubview:overlayView];
The overlay appears in a weird position (the top of it is some 50px away from the bottom of the navigation bar). What's more, apart from the background of the overlay, no elements in the overlay can be seen. It's just a blank red canvas. I have double checked that the elemenets' alpha values are 1, they are set to be not hidden, and they are also set explicitly in the initWithFrame of the overlay:
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor redColor]; // red canvas shows up
self.title.textColor = [UIColor blackColor]; // title can't be seen; why not?
self.body.textColor = [UIColor blackColor]; // body can't be seen; why not?
}
return self;
}
The reason I don't directly put overlay in the controller's xib and then simply change it's hidden property is that this overlay is to be used by multiple controllers, and I'd like to re-use it, thus putting it as a separate view.
What am I doing wrong?
The parent view (view controller's view) is responsable to set the child view's frame. If you use Auto Layout you need to use setTranslateAutoresizingMaskIntoConstraints to NO and add the desired constraints in code. Keep in mind that the child's frame will be set after viewDidLayoutSubviews is called.
If you don't use Auto Layout just set the frame using setFrame method in viewWillAppear.
It turns out I had to load the nib from within the view's own initWithFrame.
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
id mainView;
if (self) {
NSArray *subviewArray = [[NSBundle mainBundle] loadNibNamed:#"MyOverlayView" owner:self options:nil];
mainView = [subviewArray objectAtIndex:0];
}
return mainView;
}
- (void)awakeFromNib {
[super awakeFromNib];
}
The code above fixed it.

UISegmentedControl within UIView does not respond to change event

I have programmatically created a basic app on iOS7 SDK :
Created two UINavigationController
Added a view to each of them
Created a UITabBarController with two items
Added each UINavigationController to its respective UITabBarController
This is working fine, and everything is done programmatically. My project only consists in a simple window app template, without any xib nor storyboard, and everything is done within application didFinishLaunchingWithOptions: of my AppDelegate.m.
I am trying to add a UISegmentedControl (still programmatically) as a subview of the view of the first UINavigationController, as follows :
// First navigation controller
UINavigationController *firstNavController = [[UINavigationController alloc] init];
firstNavController.navigationBar.barTintColor = [UIColor redColor];
firstNavController.title = #"First";
firstNavController.navigationBar.topItem.title = #"First top";
firstNavController.tabBarItem.image = [UIImage imageNamed:#"FirstTab"];
// First view
UIView *firstView = [[UIView alloc] init];
firstView.backgroundColor = [UIColor yellowColor];
// Add a segmented control to this view
UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:
[NSArray arrayWithObjects:#"One", #"Two", nil]];
// Register an event handler
[segmentedControl addTarget:self action:#selector(segmentedControlSelectedIndexDidChange:)
forControlEvents:UIControlEventValueChanged];
// Shape it and select its first item
segmentedControl.frame = CGRectMake(10, 100, 300, 20);
segmentedControl.selectedSegmentIndex = 1;
// add the segmented control to the view
[firstView addSubview:segmentedControl];
// and the view to the first tab's navigation controler
[firstNavController.view addSubview:firstView];
The UISegmentedControl DOES show up, but touch events are not handled.
If I change my code and add the UISegmentedControl directly within the UINavigationController, touch events are actually responding :
// and the segmented control directly within the navigation controller
[firstNavController.view addSubview:segmentedControl];
What am I doing wrong, and what should I do to have it respond to it's touch events ?
You need to set the size of the view.
Confusingly a view will be visible even if it is too small to fit it's content but will only respond to touches over the area of it's offical size.
You should not be adding a subview directly to the navigation controllers view.
'firstView' should be encapsulated into a UIViewController. And create your navigation controller with [[UINavigationController alloc] initWithRootViewController:myFirstViewController];

Subclass UIView from ViewController

I'm trying to show an onscreen tutorial (like a picture with hints) in my viewController. I only know how to "open" a UIView with its drawRect method, where my paint code is inside, from the AppDelegate with:
BannerView *view = [[BannerView alloc] initWithFrame:self.window.frame];
[self.window addSubview:view];
[self.window makeKeyAndVisible];
Is it possible to activate the UIView (BannerView) by a button from inside a ViewController?
Thank you very much!
Simply use this code:
BannerView *view = [[BannerView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:view];
in your button action method (if it is defined in your controller class). See this S.O. question to know how to create a button programmatically. Otherwise, you can use interface builder for that.
Using self.view.bounds in initWithFrame will make your banner view as large as the controller's view (which could be smaller than the display).
I believe what you are looking for is adding an event handler to a button on the view controller that will create the view and add the view by using something like
BannerView *view = [[BannerView alloc] initWithFrame:CGRectMake(x,y,width,height)];
[self.view addSubview:view];
where self is the view controller.

placing a view right behind my tab bar

I have a tab bar with 3 buttons, each of which loads a different controller and hence a different view.
I would like to place a UIView right behind my tab bar so that it is visible on all 3 different sub-controllers.
How can I achieve that?
It's pretty easy (this is using a storyboard) :
• Create a subclass of UITabBarController (I'll call it "TabViewController").
• In your storyboard, select your UITabBarViewController, and give it the class `TabViewController (on the right bar, 3rd section, custom class).
• In your TabViewController.m file, use this code :
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
UIView *theView = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 50, 50)];
theView.backgroundColor = [UIColor redColor];
[self.view addSubview:theView];
[self.view bringSubviewToFront:self.tabBar];
}
You can do whatever you want with theView before you add it to self.view, here I just create a 50x50 red square at the position (50, 50). The view will stay on top of everything else !
Run & have fun !
add that green banner on Window in appDelegate.
[self.window addSubview:greenBannerView];

Change background on a UITableView embedded in a UIViewController on iOS 5

I am trying to change the grey gradient background on an embedded UITableView to the color I have set on the parent view in the Storyboard.
I have been looking around, and found the following threads:
Change iPhone tableview (style grouped) background color while preserving texture
How can I set the background of UITableView (the tableview style is “Grouped”) to use an image?
UITableView backgroundColor always gray on iPad
I have an IBOutlet in the parent controller connecting the two views.
My implementation looks as follows:
- (void)viewDidLoad {
[super viewDidLoad];
[activeShipmentsTable setBackgroundView:nil];
[activeShipmentsTable setBackgroundView:[[[UIView alloc] init] autorelease]];
[activeShipmentsTable setBackgroundColor:UIColor.clearColor];
}
What am I doing wrong?
Thanks.
Try setting et the background color on the table's background view, not the table itself.
UIView *view = [[[UIView alloc] init] autorelease];
view.backgroundColor = [UIColor redColor];
self.tableView.backgroundView = view;

Resources