Every UIViewController of my app is using the UITextField delegates, like:
- (void)textFieldDidBeginEditing:(UITextField*)textField {
self.responder = textField;
}
- (BOOL)textFieldShouldReturn:(UITextField*)textField {
double elementYPosition = self.responder.frame.origin.y;
double elementHeight = self.responder.frame.size.height;
double scrollYPosition = self.scrollView.contentOffset.y;
/* some logic */
}
Now I'm trying to create a base view controller, so I can inherit use it all around, reusing the methods. The responder property in the base view controller works just fine, because the UITextField delegate set its value, but the scrollview is a IBOutlet, and I'm not really sure how to design this base class:
#import "ViewControllerBase.h"
#interface ViewControllerBase ()
#property (weak, nonatomic) UIView* responder;
#property (weak, nonatomic) IBOutlet UIScrollView *scrollView; /* ??? */
#end
#implementation ViewControllerBase
-- methods
#end
In the subclass header:
#property (weak, nonatomic) UIScrollView *scrollView;
In the subclass load method:
self.scrollView = (UIScrollView *)self.view.subviews[0];
But it only works because my view controllers are always in the following format:
UIViewController (self)
UIView (self.view)
UIScrollView (self.view.subviews[0])
UILabel
UIElement
UIElement
UIElement
Related
I am trying to find a way to initialise a view controller which has IBOutlets to a custom view that I have created in a XIB.
Here is the code where I initialise my class:
MyContentViewController *pageContentViewController = [[MyContentViewController alloc] init];
self.pageContent = pageContentViewController;
[pageContentViewController view];
MyContentViewController has the following properties:
#interface MyContentViewController : UIViewController
#property (nonatomic, weak) IBOutlet MyContentView *topLeftView;
#property (nonatomic, weak) IBOutlet MyContentView *topRightView;
#property (nonatomic, weak) IBOutlet MyContentView *bottomLeftView;
#property (nonatomic, weak) IBOutlet MyContentView *bottomRightView;
In MyContentViewController xib I have 4 views which I have set as MyContentView and have hooked the IBOutlet's above to the views in the storyboard.
The custom view is defined as following:
#import <UIKit/UIKit.h>
#interface MyContentView : UIView
#property (nonatomic, strong) IBOutlet UILabel *labelView;
#end
However when I run the application, I get the 4 views I have added in the MyContentViewController xib. However none of them display the UILabel from the custom UIView.
I have added the following in MyContentView:
- (void)awakeFromNib {
NSLog(#"VIEW AWAKE");
}
This get printed out so the views are being loaded. However how can I get them to display using the 4 IBOutlets.
Here is a picture of the app running with the view. There is no labels on the 4 views:
I see that your "MyContentView" has a nib of it's own. Loading a custom UIView class which has a nib layout from another nib is a bit more complex.
I think this blog post contains the answer
I currently have a header that displays a name, time, and a couple of buttons. This header should only appear if an appointment is selected in a dashboard, which is irrelevant here. However, once i logout and log back in, with no patient selected, the header view is displayed. I think this is because I did not deallocate the appointment object, and i'm not sure how to do that (i'm new to iOS programming).
Here's my code:
So I have the interface
#interface DashboardVC : CommonVC <UIActionSheetDelegate, HeaderViewDelegate, PracticeServiceDelegate> {
IBOutlet HeaderView *_headerView;
}
And inside the HeaderView object i have these properties:
#property (strong, nonatomic) CCAppointment *appointment;
#property (strong, nonatomic) IBOutlet UIButton *backButton;
#property (strong, nonatomic) IBOutlet UIView *currentPatientView;
#property (strong, nonatomic) IBOutlet UIImageView *avatarImageView;
#property (strong, nonatomic) IBOutlet UILabel *patientNameLabel;
I then, in dashboard VC, want to deallocate, but i'm not sure how... this is what i have:
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
How do I deallocate the properties so that the headerVIew does not show up?
if you want to destroy _headerView try:
[_headerView removeFromSuperview];
_headerView = nil;
View does not know about the model. I have custom view:
#interface CustomView : UIView
#property UIImageView *imageView;
#property UILabel *labelView;
#property UILabel *dateLabelView;
#property UIImageView *badgeView;
...
#end
Set data in ViewController:
-(void)viewDidLoad
{
[super viewDidLoad];
...
//Install data from model in view
self.customView.labelView.text = self.model.title;
self.customView.badgeView.hidden = self.model.isBadge;
self.customView.dateLabelView.text = [self formatDate:self.model.createDate];
...
}
How to use CustomView in other ViewControllers, without having to copy code and or creating the following method in the class CustomView:
- (void)setData:(id)data;
because View does not know about the model.
I have a UIView with two UILabel that I want to reuse in more than one UIViewController. I use storyboard and I assign a custom class alertView:UIView that I declared.
file AlertRemote.h
#interface AlertRemote: UIView
#property (weak, nonatomic) IBOutlet UILabel *label1;
#property (weak, nonatomic) IBOutlet UILabel *label2;
-(void) setTextLabel;
file AlertRemote.m
-(void) setTextLabel{
[ _label1 setText:#"attention..."];
[_label2 setText:#"the program..."];
}
file Controllo.m
//the view present in the storyboard alertView linked to the uiview
#property (strong, nonatomic)IBOutlet AlertRemote *alertView;
#property AlertRemote *alRemView;
[super viewDidLoad];
_alertView=_alRemView; [_alertView setTextLabel];
[_alertView setTextLabel];
if I put some breakpoints inside setTextLabel the code don't works
thanks!!
In order for the custom alert to work, you need to initialise it.
AlertRemote *alRemView;
alRemView = [[AlertRemote alloc]init];
[alRemView setTextLabel];
I think you are not initializing the property alertview. If you are initializing the property alertview then try to set directly with out using alremView.
I found a lot of how to use methods of chlidViewController. But I couldn't find how to change and set value of uitextfield and uiswitch from childViewController.
ChildViewController.h:
#protocol VVInformationTableViewControllerDelegate;
#interface VVInformationTableViewController : UITableViewController
#property (weak, nonatomic) id<VVInformationTableViewControllerDelegate> delegate;
#property (weak, nonatomic) IBOutlet UITextField *nameTextField;
#property (weak, nonatomic) IBOutlet UITextField *surnameTextField;
#property (weak, nonatomic) IBOutlet UITextField *emailTextField;
#property (weak, nonatomic) IBOutlet UITextField *locationTextField;
#property (weak, nonatomic) IBOutlet UITextField *headlineTextField;
#property (weak, nonatomic) IBOutlet UITextField *positionTextField;
#property (weak, nonatomic) IBOutlet UITextField *companyTextField;
#property (weak, nonatomic) IBOutlet UISwitch *messagesEnable;
#end
ParentViewControler.m:
- (void)viewDidLoad
{
self.currentAttendee = [VVAPIClient sharedClient].currentUser;
NSParameterAssert(self.currentAttendee);
[super viewDidLoad];
[self.navigationController setNavigationBarHidden:YES];
self.infoTableController = [[VVInformationTableViewController alloc] initWithNibName:#"InformationTableViewController" bundle:nil];
[self addChildViewController:self.infoTableController];
}
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
self.infoTableController.nameTextField.text = self.currentAttendee.firstName?:#"";
self.infoTableController.surnameTextField.text = self.currentAttendee.lastName?:#"";
self.infoTableController.emailTextField.text = self.currentAttendee.email?:#"";
self.infoTableController.locationTextField.text = self.currentAttendee.location?:#"";
self.infoTableController.headlineTextField.text = self.currentAttendee.headline?:#"";
self.infoTableController.positionTextField.text = self.currentAttendee.position?:#"";
self.infoTableController.companyTextField.text = self.currentAttendee.company?:#"";
}
-(void)viewDidLayoutSubviews{
self.infoTableController.messagesEnable.on = NO;
self.infoTableController.nameTextField.tag = 0;
self.infoTableController.surnameTextField.tag = 1;
self.infoTableController.emailTextField.tag = 2;
self.infoTableController.locationTextField.tag = 3;
self.infoTableController.headlineTextField.tag = 5;
self.infoTableController.positionTextField.tag = 6;
self.infoTableController.companyTextField.tag = 7;
}
Thanks for help.
As david says in his comment, don't.
It violates the encapsulation of the other view controller, and leads to spaghetti code.
You should treat another VCs (View Controller's) views as private.
What you should do is add properties to the child view controller to hold strings and other state data that you need to display. Then in your child view controller's viewWillAppear method, you can take the settings and apply them to your view hierarchy.
In your case, since what you're doing is displaying a whole bunch of information about "currentAttendee", (which I guess is a model object) you might want to think about passing a pointer to the whole attendee object to the child, and letting it display the information itself.
Or, of the child can edit the object, you might want to pass a copy, and use a delegate method when you want to commit the changes made in the child, or simply return if you want to discard changes.