M learn Container View using objective c.
Here, try to display two container one by one using segmented Controller.
Two container use container name is containerViewA, containerViewB.
I am running the app that time only containerViewB is load.
Code:
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UIView *containerViewA;
#property (weak, nonatomic) IBOutlet UIView *containerViewB;
#end
- (IBAction)ShowComponent:(UISegmentedControl *)sender {
if (sender.selectedSegmentIndex == 0) {
[UIView animateWithDuration:(0.5) animations:^{
self.containerViewA.alpha = 1;
self.containerViewB.alpha = 0;
}];
} else {
[UIView animateWithDuration:(0.5) animations:^{
self.containerViewA.alpha = 0;
self.containerViewB.alpha = 1;
}];
}
}
Update:
Update 1:
Storyboard side panel.
make sure #property (weak, nonatomic) IBOutlet UIView *containerViewA; and #property (weak, nonatomic) IBOutlet UIView *containerViewB; are connected properly.
Related
I want to change my calendar height's constraint 124 to zero when calendar button is clicked how can I do that? I want to use button statement but I couldn't at objective c. Thanks.
#property (weak, nonatomic) IBOutlet UIBarButtonItem *calendarButton;
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *heightOfCalendar;`
- (IBAction)calendarAction:(id)sender {
}
you need to set constant property
heightOfCalendar.constant = requiredheight
You can Do like this to change size on each tap
- (IBAction)calendarAction:(id)sender {
sender.selected = !sender.selected;
heightOfCalendar.constant = (sender.selected)?0:124;
}
Doing it with an animation will looks good
(IBAction)calendarAction:(id)sender {
[UIView animateWithDuration:0.5
animations:^{
heightOfCalendar.constant =0;
[self.view layoutIfNeeded];
}];
}
Write this code in your IBAction:
- (IBAction)calendarAction:(id)sender {
self.heightOfCalendar.constant = 0;
}
Also make sure you have your IBAction connection set properly.
And I see a ` symbol at the end of the following statement:
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *heightOfCalendar;`
I'm facing a bit complicated (at least it looks like it to me) problem with a custom UIView that I made (called EventBadge).
Here's the code of my custom class:
EventBadge.h
#interface EventBadge : UIView
- (void)setBadgeFillColor:(UIColor *) color;
- (void)setBadgeBorderColor:(UIColor *) color;
- (void)setBadgeIcon:(MyCustomIcons) icon;
#end
EventBadge.m
#implementation EventBadge
UIColor *badgeFillColor;
UIColor *badgeBorderColor;
MyCustomIcons badgeIcon;
- (void)drawRect:(CGRect)rect {
// Gets graphic context
CGContextRef context = UIGraphicsGetCurrentContext();
// Sets fill and border colors for cirlce
CGContextSetFillColor(context, CGColorGetComponents([badgeFillColor CGColor]));
CGContextSetStrokeColor(context, CGColorGetComponents([badgeBorderColor CGColor]));
// Set border line width
CGContextSetLineWidth(context, 2.0);
// Set rect containing circle as inset of rect
CGRect circle = CGRectInset(rect, 1, 1);
// Draw fill and stroke into rect
CGContextFillEllipseInRect(context, circle);
CGContextStrokeEllipseInRect(context, circle);
// Draws icon
[self drawBadgeIconInside:circle];
// Fill graphic context with path
CGContextFillPath(context);
}
/**
* Sets the background color for the badge and forces refresh
*/
- (void)setBadgeFillColor:(UIColor *) color{
badgeFillColor = color;
[self setNeedsDisplay];
}
/**
* Sets the background color for the badge and forces refresh
*/
- (void)setBadgeBorderColor:(UIColor *) color{
badgeBorderColor = color;
[self setNeedsDisplay];
}
/**
* Sets the icon for the badge and forces refresh
*/
- (void)setBadgeIcon:(MyCustomIcons) icon{
badgeIcon = icon;
[self setNeedsDisplay];
}
/**
* Draws the badge icon inside a rectangle
*/
- (void)drawBadgeIconInside:(CGRect) rect {
// Creates the inner rectangle from the original one (20x20)
CGRect iconContainer = CGRectInset(rect, 5, 5);
// Switch on badgeIcon: many different supported types
switch (badgeIcon) {
case EventLocation:
[StyleKit drawIconLocationWithFrame:iconContainer colorBase:[StyleKit blackMP]];
break;
case EventCar:
[StyleKit drawIconCarWithFrame:iconContainer colorBase:[StyleKit blackMP]];
break;
default:
MyLog(MyLogLevelError, #"INVALID MyCustomIcon");
break;
}
}
#end
I have a UITableView that can be filled with three different types of UITableViewCell, let's say TypeA, TypeB and TypeC.
TypeA and TypeB have different elements inside (UILabels, UIViews and so on) and they both have my EventBadge. TypeC is made of standard elements only.
Here's the code for all cell types:
TypeA.h
#interface TypeACell : UITableViewCell
#property (strong, nonatomic) IBOutlet UIView *prevRouteView;
#property (strong, nonatomic) IBOutlet UIView *nextRouteView;
#property (strong, nonatomic) IBOutlet UILabel *addressLabel;
#property (strong, nonatomic) IBOutlet EventBadge *eventBadgeView;
#end
TypeB.h
#interface TypeBCell : UITableViewCell
#property (strong, nonatomic) IBOutlet EventBadge *eventBadgeView;
#property (strong, nonatomic) IBOutlet UIView *prevRouteView;
#property (strong, nonatomic) IBOutlet UIView *nextRouteView;
#property (strong, nonatomic) IBOutlet UILabel *titleLabel;
#property (strong, nonatomic) IBOutlet UILabel *addressLabel;
#property (strong, nonatomic) IBOutlet UILabel *startTime;
#property (strong, nonatomic) IBOutlet UILabel *endTime;
#property (strong, nonatomic) IBOutlet CalendarColorView *calendarColor;
#end
TypeC.h
#interface TypeCCell : UITableViewCell
#property (strong, nonatomic) IBOutlet UIView *routeView;
#property (strong, nonatomic) IBOutlet UILabel *duration;
#property (strong, nonatomic) IBOutlet UILabel *startTime;
#property (strong, nonatomic) IBOutlet UILabel *endTime;
#property (strong, nonatomic) IBOutlet CalendarColorView *calendarColor;
#property (strong, nonatomic) IBOutlet TransportTypeIconView *transportTypeView;
#end
I choose the type of cell inside cellForRowAtIndexPath method of my ViewController looking at the type of object stored in _tableviewData (the array used to fill the tableView). The code looks like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if([_tableviewData[indexPath.row] isKindOfClass:[EventTypeA class]]){
EventTypeA *event = (EventTypeA *)_tableviewData[indexPath.row];
return [self tableView:tableView createTypeACell:event atIndexPath:indexPath];
}
else if([_tableviewData[indexPath.row] isKindOfClass:[EventTypeB class]]) {
EventTypeB *event = (EventTypeB *)_tableviewData[indexPath.row];
return [self tableView:tableView createTypeBCell:event atIndexPath:indexPath];
}
else {
EventTypeC *event = (EventTypeC *)_tableviewData[indexPath.row];
return [self tableView:tableView createTypeCCell:event atIndexPath:indexPath];
}
}
Inside each method createTypeXCell I work directly on elements and set their properties. Everything is working as expected except properties set on my custom view. So TypeC works perfectly and everything in TypeA and TypeB works as expected except the settings for colors and icons on my eventBadgeView.
The behaviour that I get is that each eventBadgeView, no matter which UITableViewCell belongs to, gets painted with the properties of the last eventBadgeView being worked (the last item of the array).
If I scroll a little bit up or down the UITableView, enough to render one item, that item gets updated well, with the properties I set previously.
But if I scroll too much everything gets messed up once again.
I've noticed that drawRect gets always called a lot later with regards to setNeedsDisplay and I've learned that this is meant to be like this.
I've read on lots of SO posts (I'm not linking here all of them) and based on those what I've tried to do (with no luck) is:
call [cell.eventBadgeView setNeedsDisplay] inside the method that
creates the cell after setting properties
put all the part of setting cell properties and [cell.eventBadgeView setNeedsDisplay] inside dispatch_async
use a CALayer to "force" drawRect to be executed synchronously
Maybe as I'm new to ObjectiveC I'm missing some basic things, and I have big doubts on my custom EventBadge : UIView class since everything else works fine.
Thanks in advance for the help! :)
You should declare those variables out the implementation body otherwise, they'll be threated like gloabal variables in the .m file (more info about this here)
UIColor *badgeFillColor;
UIColor *badgeBorderColor;
MyCustomIcons badgeIcon;
put them in an interface (inside the .m file or directly in the .h) and declare them as #property
#interface MPEventBadge ()
#property (strong, nonatomic) UIColor *badgeFillColor;
#property (strong, nonatomic) UIColor *badgeBorderColor;
#property (nonatomic) MPInsertEventIcons badgeIcon;
#end
you can then access the variable like
_badgeFillColor = color;
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;
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.
I set UIButton myButton to hidden on viewDidLoad
In a splitviewcontroller I have it so that when I click on a tablecell, certain items unhide which works great for my textviews but my button is giving me this:
ERROR: member reference base type void is not a structure or union
Here is some snippet of code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0) {
detailViewController.myButton.hidden= NO;
detailViewController.textView1.hidden= NO;
detailViewController.textView2.hidden= NO;
}
in the .h file there is
#property (strong, nonatomic) DetailViewController *detailViewController;
in DetailViewController is where the button and textviews are declared as
#interface DetailViewController : UIViewController <UISplitViewControllerDelegate>{
IBOutlet UIButton *myButton;
IBOutlet UITextView *textView1;
IBOutlet UITextView *textView2;
}
#property (strong, nonatomic) IBOutlet UITextView *textView1;
#property (strong, nonatomic) IBOutlet UITextView *textView2;
#property (strong, nonatomic) UIButton *myButton;
-(IBAction)myButtonPressed;
#end
IBAction myButtonPressed in the DetailViewController.m is
-(IBAction)myButtonPressed{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
RootViewController *RVC = [storyboard instantiateViewControllerWithIdentifier:#"Root"];
[UIApplication sharedApplication].delegate.window.RootViewController = RVC;
}
Anyone have any thoughts on why the button won't behave like the other two will? Is it because I gave it an IBAction??
You forget to Put IBOutlet at the first of button creation it should be
#property (strong, nonatomic) IBOutlet UIButton *myButton; OR
#property (nonatomic, weak) IBOutlet UIButton *myButton;
And give proper connection to file's owner.
Button should be a IBOutlet and please correct it and update XIB references and you should be good.
#property (nonatomic, weak) IBOutlet UIButton * myButton;
link this to UIButton is XIB if you are using one.