I am trying to add the Tapku calendar to my app. I am using storyboards, I have added the Tapku library, imported the necessary files and add the TKCalendarMonthViewDelegate methods. I am adding the calendar to a UIView called calendarView. When I run the app the calendar doesn't appear, just the view with nothing inside it.
-(void)viewDidLoad
{
[super viewDidLoad];
[self.navigationController setNavigationBarHidden:NO animated:YES];
self.navigationItem.hidesBackButton = YES;
calendar = [[TKCalendarMonthView alloc] init];
calendar.delegate = self;
calendar.dataSource = self;
calendar.frame = CGRectMake(0, 0, calendar.frame.size.width, calendar.frame.size.height);
// Ensure this is the last "addSubview" because the calendar must be the top most view layer
[self.view addSubview:calendar];
[calendar reload];
// Do any additional setup after loading the view.
}
Can anyone help me please?
try by specifing frame points directly,like this
calendar.frame = CGRectMake(0, 0, 320,400);
If you're adding TKCalendarMonthView to your view controller using a Storyboard, then you should not also be initializing another instance of TKCalendarMonthView in your view controller's -viewDidLoad method.
In your Storyboard:
Add a TKCalendarMonthView to your view controller.
Set the size contraints.
Connect TKCalendarMonthView to the outlet (see below) in your view controller.
In your view controller:
Add an outlet for the TKCalendarMonthView.
#interface YourViewController () <TKCalendarMonthViewDataSource, TKCalendarMonthViewDelegate>
#property (weak, nonatomic) IBOutlet TKCalendarMonthView *calendarMonthView;
#end
In -viewDidLoad, connect TKCalendarMonthView's delegate and data source. Note, you can also do this in the Storyboard if you first add the IBOutlet annotate to the delegate and dataSource properties in TKCalendarMonthView.h
#implementation YourViewController
...
- (void)viewDidLoad
{
[super viewDidLoad];
...
self.calendarMonthView.delegate = self;
self.calendarMonthView.dataSource = self;
However these changes alone will not get the TKCalendarMonthView to display the calendar. The reason is that the view is getting initialized by the Storyboard but none of the existing -init methods are called when loaded by the Storyboard. So you will need to add an -initWithCoder: method to TKCalendarMonthView.m. The following example will call the default -init: method.
-(id)initWithCoder:(NSCoder *)aDecoder
{
self = [self init];
if (self) {
}
return self;
}
If you do all this, you should see the rendered calendar instead of a blank view.
Related
I'm fairly new to xcode, but i'm having some trouble adding admob to my app.
I followed the instructions for Admob but the ads are not showing up.
Im thinking i need to add the new view i created AdViewController to appsdelegate. Is there a code i should add for that?
BTW: Im using a tabbar controller as the rootviewcontroller
In the view controller in which you want to display the add , do the following :
.h
#interface MyViewController: UIViewController
{
GADBannerView *adBanner;
}
#end
.m
#implementation MyViewController
// In the viewDidLoad method of the controller create a adbanner
-(void) viewDidLoad
{
[super viewDidLoad];
adBanner_ = [[GADBannerView alloc] initWithFrame:CGRectMake(0, 0, GAD_SIZE_320x50.width, GAD_SIZE_320x50.height)];
adBanner_.delegate = self;
adBanner_.rootViewController = self;
adBanner_.adUnitID = the_ad_ID_given_by_Google;
GADRequest *request = [GADRequest request];
[adBanner loadRequest:request];
[self.view addSubview:adBanner];
}
#end
You need to set the rootViewController to be the UITabBarController, but you need to add the GADBannerView object into the view for the view Controller that's currently being shown.
There's an example using a custom UITabBar solution here.
I am trying to add a static fixed image to a UITableViewController, but when I do the standard [self.view addSubview:imageView]; the image is placed on the tableview and moves with the scrolling.
Is there any way to do this so that the image stays fixed?
I know one method would be to create a UIViewController, then add the UIImageView and a UITableView, but unfortunately, I am using a custom UITableViewController (just a library found on gihub to do what I needed), so my controller must be a UITableViewController.
Is there any way to do this? I've been going at this for a while with no luck.
Cheers,
Brett
There is no problem using UIViewController idea. You just keep 2 view controllers: 1) UIViewController, which has the UIImageView inside, and subview the view of 2) the UITableViewController. If necessary, make the UITableViewController a strong reference of the UIViewController.
I have done something similar all the time.
Yes, there are few ways. You could create your view hierarchy programmatically at
viewDidLoad or use a NIB file. Make sure that you correctly link the delegates and view properties.
If a nib file is specified via the initWithNibName:bundle: method (which is declared by the superclass UIViewController), UITableViewController loads the table view archived in the nib file. Otherwise, it creates an unconfigured UITableView object with the correct dimensions and autoresize mask. You can access this view through the tableView property.
If a nib file containing the table view is loaded, the data source and delegate become those objects defined in the nib file (if any). If no nib file is specified or if the nib file defines no data source or delegate, UITableViewController sets the data source and the delegate of the table view to self.
As https://stackoverflow.com/a/6961973/127493 say, UITableViewControllers can be replaced by simple UIViewControllers.
In fact, the trick is to add an UITableView to you UIViewController, make it delegate and etc..., and add it to your UIViewController.view.
So you will be able to add some "sister" views to your controller main view.
In my case, I am adding a an Image ( actually button with image) and when user touches on image, it will disappear and tableview will be shown.
so i am disabling scroll first then enable it back
find code below
// in viewDidLoad
[self.view addSubview:imgview];
tbl.scrollEnabled = NO;
// in -(IBAction)btnClicked:(id)sender
[imgview removeFromSuperview];
tbl.scrollEnabled = YES;
Thats working for me.
Do NOT use UITableViewController at all (I never use it and as I've heard nearly any developer uses it). It is a nightmare when you want to customize design with it.
Create your own subclass of UIViewController (MYTableViewController), add UITableView *tableView instance #property and #synthetize it:
#interface MYTableViewController : UIViewController <UITableViewDelegate,UITableViewDataSource> {
UITableView *tableView;
}
#property (nonatomic, retain) IBOutlet UITableView *tableView;
#end
Then in implementation add it to the view (using XIB or viewDidLoad method):
#implementation MYTableViewController
#synthesize tableView;
// If not XIB used:
-(void)viewDidLoad{
[super viewDidLoad];
CGRect frame = self.view.bounds;
self.tableView = [[[UITableView alloc] initWithFrame:frame style:UITableViewStylePlain] autorelease];
tableView.dataSource = self;
tableView.delegate = self;
[self.view addSubview:tableView];
// And here you van add your image:
[self.view addSubview:imageView];
}
// Do not forget to release it and clear delegate and datasourcce when view uloads:
#pragma mark - Memory management:
-(void)dealloc{
self.tableView.delegate = nil;
self.tableView.dataSource = nil;
self.tableView = nil;
[super dealloc];
}
- (void)didReceiveMemoryWarning {
self.tableView.delegate = nil;
self.tableView.dataSource = nil;
self.tableView = nil;
[super didReceiveMemoryWarning];
}
-(void)viewDidUnload{
self.tableView.delegate = nil;
self.tableView.dataSource = nil;
self.tableView = nil;
[super viewDidUnload];
}
#end
I have a UIViewController called LaunchController that is launched in my iPhone app when the app first opens:
#interface LaunchController : UIViewController<UINavigationControllerDelegate, UIImagePickerControllerDelegate>
Then, when a button is clicked, I push another view controller:
MainController *c = [[MainController alloc] initWithImage:image];
[self presentModalViewController:c animated:NO];
MainController has the following constructor, which I use:
- (id)initWithImage:(UIImage *)img
{
self = [super init];
if (self) {
image = img;
NSLog(#"inited the image");
}
return self;
}
and then it has a viewDidLoad method as follows:
- (void)viewDidLoad
{
NSLog(#"calling view did load");
[super viewDidLoad];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
[self.view addSubview:imageView];
NSLog(#"displaying main controller");
}
When the program runs, I see that the constructor for MainController is called (due to the output of NSLog), however viewDidLoad never gets called, even though I am calling presentModalViewController. Why is this? Why isn't viewDidLoad being called?
I think it is something as followings. When you need the property of view inside UIViewController, it will be loaded with lazy manner.
- (UIView *)view
{
if (_view == nil) {
[self loadView]; //< or, the view is loaded from xib, or something else.
[self viewDidLoad];
}
return _view;
}
After the view initialized, it will call viewDidLoad to inform the UIViewController.
You aren't loading your view controller from a xib file, and from comments you don't have anything in loadView (which is where you would create your view controller's view if you were not using a xib file).
Therefore, your view isn't being loaded, so viewDidLoad is never called.
Typically you would use initWithNibName: to initialise a new view controller, and then set the image after it (so expose the image as a property).
viewDidLoad will be called as soon as your controller's view property is accessed, that is when you display it for the first time or request it (e.g. have some code that calls c.view.
The reason viewDidLoad is not being called is because you aren't loading a view.
In your init method:
self = [super init];
means that you are just creating a naked view from scratch. not loading one from a nib.
try this instead:
self = [super initWithNibName:nil bundle:nil];
If you have a xib or nib file with the same name as the view controller class it should find if. Otherwise, you can just give a nibName that works.
UPDATE:
If you are not using nib files, then the appropriate method is NOT viewDidLoad. You have to implement loadView instead of viewDidLoad.
In your specific case, just put everything that is currently in viewDidLoad into loadView.
I have created a navigation-based application. In that, I have created MyTableViewController using uiviewcontroller.class.
#import "RootViewController.h"
#import "MyTableViewController.h"
#implementation RootViewController
- (void)viewDidLoad
{
[super viewDidLoad];
MyTableViewController *tableViewController = [[MyTableViewController alloc] init];
}
#end
#import "MyTableViewController.h"
#implementation MyTableViewController
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"sedfsdsd");
}
#end
I don't want to show the view when the instance is created. I want to call the constructor method. I don't know how to do it. Please help me out.
#Caroline have described very good.
A normal method of your class could serve your purpose and you can name that something ViewContruction and define it in your MyTableViewController class.
-(void) ViewContruction
{
//Create all your views here
//Add that to the self.view of your controller
}
Call the above function explicitly on the instance of your view controller.
Just creating a UIViewController instance does not load the view.
If you have something like [self.view addSubview:tableViewController.view] then when that statement is executed, viewDidLoad will get executed.
However, if it's a navigation-based app, then you will need to push the viewcontroller to see it, rather than adding the subview as above.
For example:
Settings *settingsController = [[Settings alloc] initWithNibName:#"Settings" bundle:nil];
settingsController.contentSizeForViewInPopover = settingsController.view.frame.size;
[self.navigationController pushViewController:settingsController animated:YES];
[settingsController release];
I have a View Controller that initializes a UIView as its view. That view initializes another UIView as a subview. Both UIViews communicate with the View Controller through a delegate/protocol.
Each UIView creates an instance of the ViewController and makes it equal to the delegate:
ViewController *aDelegate = [[ViewController alloc] init];
self.delegate = aDelegate;
PROBLEM: The View Controller has a variable called (int)selection that is modified by both UIViews. Both views must know how each other modified the variable, but since each has a different instance of the View Controller that communication is impossible. How would I fix this problem?
Thanks a ton
EDIT: Peter mentioned assigning the delegate at the views creation which I like, but how would I do that for the subview since it is created in the UIView and not the View Controller. PS. In reality it is a subview of a subview of a subview so can I create them all in the View Controller and then assign it as the delegate?
Tried assigning the delegate as follows but it continually crashes when I attempt to call a ViewController method from the view:
MyView *mainView = [[MyView alloc] initWithFrame:frame];
self.view = mainView;
mainView.delegate = self;
[mainView release];
The views does not need to know about each other. In your view controller you define a property for the sub view
#property (nonatomic, retain) MyView *myView;
Then you create your sub view and assign the delegate. This can be done in viewDidLoad
- (void)viewDidLoad {
[super viewDidLoad];
CGRect frame = ...;
MyView *subView = [[MyView alloc] initWithFrame:frame];
self.myView = subView;
subView.delegate = self;
[self.view addSubView:subView];
[subView release];
self.view.delegate = self;
}
Then in your delegate method, which I just guessed how it could look, you can update the view controller as well as the other view.
- (void)view:(MyView *)view didUpdateSelection:(int)newSelection {
self.selection = newSelection;
if (view == self.view) {
self.myView.selection = newSelection;
}
else {
self.view.selection = newSelection;
}
}
It sounds like instead of each view allocating a separate instance of the view controller, you want to assign the instance of the view controller that created the views as the delegate of each view.
One way to approach this is to have the view controller assign itself as the view's delegate when it creates the view.