I created a Subclass of UIViewController in my Project and linked it to a View which is modal-pushed by the "RootViewController". I made absolutely no changes to the derived class, but when the "SecondView" is pushed it turns black every time. If i link that view to the standard UIViewController class everything works fine?
Since the "SecondViewController" is derived from UIViewController I can only guess that the Problem has to do with the alloc/init function but I have no idea where to start.
I can provide the sample code I have in front of me now if necessary.
This is the derived subclass:
#import "SecondViewController.h"
#interface SecondViewController ()
#end
#implementation SecondViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self; }
- (void)loadView {}
- (void)viewDidLoad {
[super viewDidLoad]; }
- (void)viewDidUnload {
[super viewDidUnload];}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationPortrait); }
#end
Header:
#import <UIKit/UIKit.h>
#interface SecondViewController : UIViewController
#end
- (void)loadView
{
// If you create your views manually, you MUST override this method and use it to create your views.
// If you use Interface Builder to create your views, then you must NOT override this method.
}
FYI, the comment is automatically generated too.
Change this:
- (void)loadView
{
// If you create your views manually, you MUST override this method and use it to create your views.
// If you use Interface Builder to create your views, then you must NOT override this method.
}
To this:
- (void)loadView
{
[super loadView];
// If you create your views manually, you MUST override this method and use it to create your views.
// If you use Interface Builder to create your views, then you must NOT override this method.
}
And it will work.
Try this
-(void)loadView
{
UIView *view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
[view setBackgroundColor:[UIColor whiteColor]];
UILabel *label=[[UILabel alloc]initWithFrame:CGRectMake(10, 50, 100, 100)];
[label setText:#"HAI"];
[view addSubview:label];
self.view = view;
}
If you are trying to get the view to load before it "shows" up during the segue from IB you might want to try something like this in the destination view controller.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[self.view layoutIfNeeded];
}
Related
i get some problem by removing the Edit Button from the moreNavigationController.
I cant find the mistake, it must be a simple one.
I create some TabBarViewController connect it in the IB with my TabBarViewController.
Here is the Code:
TabBarViewController.h:
#import <UIKit/UIKit.h>
#interface TabBarViewController : UITabBarController <UINavigationControllerDelegate, UITabBarControllerDelegate>
#end
TabBarViewController.m:
#import "TabBarViewController.h"
#interface TabBarViewController ()
#end
#implementation TabBarViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.delegate = self;
[self.moreNavigationController.navigationBar setBarStyle:UIBarStyleBlackOpaque];
[self.moreNavigationController.navigationBar setBackgroundImage:[UIImage imageNamed:#"navbar.bg.png"] forBarMetrics:UIBarMetricsDefault];
[self.moreNavigationController.navigationBar.topItem setRightBarButtonItem:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
The Edit Button is stil there :/
You need to set the navigationController delegate to your tabBarController. Add the following line in your viewDidLoad method of your TabBarViewController class
self.moreNavigationController.delegate = self;
use the delegate method of UINavigationController navigationController:willShowViewController:animated: to hide the barButtonItem
Use the following code
- (void)navigationController:(UINavigationController *)navigationController
willShowViewController:(UIViewController *)viewController
animated:(BOOL)animated
{
navigationController.navigationBar.topItem.rightBarButtonItem = Nil;
}
This should work, it worked for me.
There is a more pretty solution:
tabBarController.customizableViewControllers = [];
Prasad Devadiga Thanks man!
In my TabBarViewController.m
#import "TabBarViewController.h"
#interface TabBarViewController ()
#end
#implementation TabBarViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.moreNavigationController.delegate = self;
navigationController:willShowViewController:animated:YES;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)navigationController:(UINavigationController *)navigationController
willShowViewController:(UIViewController *)viewController
animated:(BOOL)animated
{
navigationController.navigationBar.topItem.rightBarButtonItem = Nil;
}
#end
In my TabBarViewController.h
I insert this codes
#import <UIKit/UIKit.h>
#interface TabBarViewController : UITabBarController <UINavigationControllerDelegate, UITabBarControllerDelegate>
#end
This is working on IOS7
After reading all of the above and converting it to Swift 3 I noticed that when one of the view controllers which was shown after selecting the More... tab was a navigationcontroller and had a rightBarButton item, that item was removed as well! Since that is not desired, I came up with the following solution:
//
// CustomizedTabBarController.swift
//
import UIKit
class CustomizedTabBarController: UITabBarController, UINavigationControllerDelegate {
var root : UIViewController?
override func viewDidLoad() {
super.viewDidLoad()
root = self.moreNavigationController.topViewController
// Make sure the icons have the proper tint color
if let view = root?.view {
view.tintColor = UIColor.green
}
self.moreNavigationController.delegate = self
}
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
// Only hide the rightBarButtonItem when this is the morenavigationcontroller
if( viewController == root ){
navigationController.navigationBar.topItem?.rightBarButtonItem = nil
}
}
}
As an extra I also force the icons shown in the moreNavigationController to be green instead of the standard blue tintcolor since I was using green icons on the tabbar as well.
This worked for me
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
tabBarController.customizableViewControllers?.removeAll()
}
I'm trying to create & use a very simple UIView subclass for a rectangle with rounded corners. I've created a new class as follows :
RoundedRect.h
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#interface RoundedRect : UIView
#end
RoundedRect.m
#import "RoundedRect.h"
#implementation RoundedRect
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
[[self layer] setCornerRadius:10.0f];
[[self layer] setMasksToBounds:YES];
}
return self;
}
#end
I'm using iOS 5.1 with storyboards and have set the custom class property in the IB inspector window to 'RoundedRect', but when I run the app the rectangle still has square corners. Have I missed something obvious?
Thanks
Jonathan
In iOS 5 and up, there is absolutely no need to subclass - you can do it all from Interface Builder.
Select the UIView you want to modify.
Go to the Identity Inspector.
In "User Defined & Runtime Attributes", add "layer.cornerRadius" in Key Path, Type should be "Number" and whatever setting you require.
Also add 'layer.masksToBounds' as Boolean.
Done! With no subclassing, and all in IB.
The other guys have already answered the question but I would refactor it like this to enable use in nibs and in code
#import "RoundedRect.h"
#implementation RoundedRect
- (id)initWithFrame:(CGRect)frame;
{
self = [super initWithFrame:frame];
if (self) {
[self commonInit];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder;
{
self = [super initWithCoder:aDecoder];
if (self) {
[self commonInit];
}
return self;
}
- (void)commonInit;
{
CALayer *layer = self.layer;
layer.cornerRadius = 10.0f;
layer.masksToBounds = YES;
}
#end
The initWithFrame method is not called when the view is instantiated from a XIB file. Instead, the initWithCoder: initializer is called, so you need to perform the same initialization in this method.
For views that are loaded from a NIB file, the designated initializer is initWithCoder:. initWithFame: is not called in this case.
If UIView load from Nib, you should use method
- (void)awakeFromNib
I subclassed UIViewController as STViewController and noticed that classes inheriting from STViewController have their viewDidLoad method being called repeatedly. Ultimately crashing the app. STViewController is basically a blank implementation at this point. I am subclassing as shown below:
#import "STViewController.h"
#interface WelcomeViewController : STViewController {
STViewController.h
#import <UIKit/UIKit.h>
#interface STViewController : UIViewController
{
}
#end
STViewController.m
#import "STViewController.h"
#implementation STViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)loadView
{
// Implement loadView to create a view hierarchy programmatically, without using a nib.
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
viewDidLoad() from WelcomeViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
// hide the buttons
[[self signUp] setHidden: YES];
[[self logIn] setHidden: YES];
}
You are overriding loadView, but your implementation is empty, and you're not assigning a view. Remove the loadView override.
From UIViewController Class Reference (emphasis mine):
You should never call this method directly. The view controller calls
this method when the view property is requested but is currently nil.
If you create your views manually, you must override this method and
use it to create your views. If you use Interface Builder to create
your views and initialize the view controller—that is, you initialize
the view using the initWithNibName:bundle: method, set the nibName and
nibBundle properties directly, or create both your views and view
controller in Interface Builder—then you must not override this
method.
The default implementation of this method looks for valid nib
information and uses that information to load the associated nib file.
If no nib information is specified, the default implementation creates
a plain UIView object and makes it the main view.
If you override this method in order to create your views manually,
you should do so and assign the root view of your hierarchy to the
view property. (The views you create should be unique instances and
should not be shared with any other view controller object.) Your
custom implementation of this method should not call super.
i'm trying to do this from inside the .m of a custom view class that is not being loaded from the XIB, but rather programmatically:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
self.backgroundColor=[UIColor redcolor];
}
return self;
}
i have the same result whether i put the background color in the initWithFrame or other methods. the background color property doesn't take. from the controller, which owns this custom view, i can set the background color fine, with:
self.mycustomview.backgroundColor=[UIColor redcolor];
But I'd like to do this from within the custom view itself, keep stuff like this independent. both the controller and the custom view import UIKit.
I also tried this, which was available from Code Sense:
self.View.backgroundColor=[UIColor redcolor];
but that doesn't work either. i tried both view and View here. I'm sure I'm overlooking something very obvious.
in the view controller i have this, and it works fine. the custom view is called "mapButtons.h":
- (void)viewDidLoad
{
CGRect frame=CGRectMake(0, 0, 320, 460);
self.mapButtons=[[mapButtons alloc] initWithFrame:frame];
self.mapButtons.backgroundColor=[UIColor redColor];
[self.view addSubview:self.mapButtons];
the .h of the custom view is this:
#import <UIKit/UIKit.h>
#interface mapButtons : UIView
If your view is getting created from a XIB (i.e. you added it to some other view using Interface Builder), -initWithFrame: is not going to get called. An object being loaded from a XIB receives -initWithCoder: instead. Try this:
- (id)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if(self)
{
self.backgroundColor = [UIColor redColor];
}
return self;
}
I have tested again and this is the full source for what I am doing that works
// MapButtons.h
#import <UIKit/UIKit.h>
// As a note you normally define class names starting with a capital letter
// but I did test this with mapButtons as you had it
#interface MapButtons : UIView
#end
// MapButtons.m
#import "mapButtons.h"
#implementation mapButtons
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
self.backgroundColor = [UIColor redColor];
}
return self;
}
#end
// TestAppDelegate.m
#implementation TestAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
MapButtons *view = [[MapButtons alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window addSubview:view];
[self.window makeKeyAndVisible];
return YES;
}
The fact that xcode is not auto completing is odd but I seem to have this issue intermittently so I have no real solution. People sometimes suggest deleting the projects derived data and restarting xcode.
In my nib, I have a UITextView component.
In my UIViewController I have a UITextView member field and I have used IB to make sure that the two are connected (at least I think I did that by dragging from "Files Owner" and dropping it on the UITextView in IB and selecting my member variable).
Now, when I update the text via setText:, the UITextView still remains blank.
When I break into my code, the member variable (called textView) is nil.
So I am guessing I have not used IB correctly. How can I make sure that this variable is connected to the UITextView graphic element?
Here is the code
// My interface looks like
#import <UIKit/UIKit.h>
#interface DetailsController : UIViewController
{
UITextView *textView;
}
#property (nonatomic, retain) IBOutlet UITextView *textView;
#end;
// and the implementation
#import "DetailsController.h"
#implementation DetailsController
#synthesize textView;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
// Custom initialization
}
return self;
}
- (void)dealloc
{
[super dealloc];
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
// used pressed the "Done" button
- (IBAction)done
{
[self dismissModalViewControllerAnimated:YES];
}
- (void)setDetails: (NSString *)detail withQuote:(NSString *)quote
{
NSLog(#"%#", textView);
[textView setText:detail];
}
#end
save nib file after connecting outlet, build project and run, it should work if it's connected
I can't see agere you are calling setText, but I think that you try to do it in the initializer. GUI code should not be done before the viewDidLoad in the case of using XIB's or loadView if you make your GUI programatically, or the other viewWill/viewDid... methods.
The reason is because the views are not loaded before they are actually needed, it is called lazy loading. You should Google that for more info.