There is an ios library called HGKOptionPane by Jon Arrien. It is a show/hide dropdown panel. While I was implementing it to my demo app, I noticed this UIView frame linked with the UIButton.
I'm sure it has something to do with the code below, I didn't understand the code and I would appreciate if you could explain it. Most importantly, how is the UIButton linked with the UIView or Option Panel it self.
The 2 methods inside HGKOptionPanel.m :
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
- (void)drawRect:(CGRect)rect{
[super drawRect:rect];
isExpanded = YES;
}
Photo:
Option Panel is the UIView with black Background color.
The UIButton is an IBOutlet which is not linked by code.
It is actually all saved in the xib file here:
https://raw.github.com/Hegaka/HGKOptionPanel/master/HGKOptionPanel/HGKOptionPanel/en.lproj/MainWindow.xib
Related
I am subclassing an UIButton which is going to be present in all of my app's ViewControllers, kinda Navigation Button. I would like just to put it to my VC and apply custom class, without any code in ViewController itself. So, the questions:
1. is it possible?
2. I am using this code now in my UIButton custom class. What is wrong?:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self addTarget:self action:#selector(didTouchButton) forControlEvents:UIControlEventTouchUpInside];
}
return self;
}
- (void)didTouchButton {
NSLog(#"YEAH, it works, baby!");
}
UPD: seems that even initWithFrame method is not being called at all.
Loading from the nib I think.The initWithFrame method doesn't work if not called programatically.
Try -awakeFromNib Method
See this question
I have a ViewController (VCViewController) with this code in it:
touchView = [[VCTouchView alloc] initWithFrame:(CGRect){{0, 0}, 320, 480} andTheCameraController:self];
in the UIView (VCTouchView) though I have:
(id)initWithFrame:(CGRect)frame andTheCameraController:(VCViewController*)cameraController
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
Basically I have a ViewController which I want to add an overlay. On this overlay will be a button for the user to press that will take a photo. Quite simple requirement, yet I cannot understand why it can't see the parameter called andTheCameraController?
Any help greatly appreciated.
Mike
Have you added the new method to your VCTouchView.h file?
-(id)initWithFrame:(CGRect)frame andTheCameraController:(VCViewController *)cameraController;
In my application I've subclassed UIView and it has three ivars declared in .m file (2UIButton and an UITextField ). I use this object by drag the UIView from the objects library and convert them to my subclass. below is my implementation
#interface Prescriber()<UITextFieldDelegate>
{
UIButton *_addButton;
UIButton *_lessButton;
UITextField *_valueField;
}
#end
#implementation Prescriber
#synthesize value=_value,intValueofStrig=_intValueofStrig;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
NSLog(#"prescriber called");
return self;
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/
-(void)layoutSubviews
{
if (!_addButton) {
_addButton=[[UIButton alloc]init];
[_addButton addTarget:self action:#selector(addbuttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[_addButton setBackgroundImage:[UIImage imageNamed:#"add1.png"] forState:UIControlStateNormal];
_addButton.layer.cornerRadius=5;
}
if (!_lessButton) {
_lessButton=[[UIButton alloc]init];
[_lessButton addTarget:self action:#selector(lessButoonClicked:) forControlEvents:UIControlEventTouchUpInside];
[_lessButton setBackgroundImage:[UIImage imageNamed:#"Minus.png"] forState:UIControlStateNormal];
}
if (!_valueField) {
_valueField=[[UITextField alloc]init];
_valueField.delegate=self;
}
///positioning the addbutton on left corner and right corner and position and
textfield in the center
}
I've done the configuring code in the -(void)layoutSubviews method as my -initwithFrame not get called as they are already in the xib file.
what I want to know is ,Is it right to do our initialization in the -layoutSubViews as there is a chance for this method to get called another time. Or am I able to invoke the
-viewDidLoad like delgate method for my subclassed View too?
Edit:- It is possible by creating an IBOutlet but that way is a constraint for me.
Do it in a private setup method:
#interface MyViewClass ()
- (void)_setup;
#end
#implementation MyViewClass
- (void)_setup
{
_addButton=[[UIButton alloc]init];
[_addButton addTarget:self action:#selector(addbuttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[_addButton setBackgroundImage:[UIImage imageNamed:#"add1.png"] forState:UIControlStateNormal];
_addButton.layer.cornerRadius=5;
_lessButton=[[UIButton alloc]init];
[_lessButton addTarget:self action:#selector(lessButoonClicked:) forControlEvents:UIControlEventTouchUpInside];
[_lessButton setBackgroundImage:[UIImage imageNamed:#"Minus.png"] forState:UIControlStateNormal];
_valueField=[[UITextField alloc]init];
_valueField.delegate=self;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self != nil)
{
[self _setup];
}
return self;
}
- (id)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (self != nil)
{
[self _setup];
}
return self;
}
#end
For IB instances, you can setup you view and initialize its subviews in -awakeFromNib:
- (void)awakeFromNib
{
[super awakeFromNib];
// your initialization code here
}
Using this method, your instance is fully initialized and the IB connections have been established. It is also guaranteed to be called exactly once (per instance). If you also create instances of this type programmatically, then you should consider a shared initialization method which can be called in -awakeFromNib.
The problem with adding subviews in the initializer is that your view is in a partially constructed state, and ultimately there may be side effects or difficulty initializing your view/object graph in a well defined and deterministic manner; -awakeFromNib at least ensures all NIB objects have been created and the connections exist, although the order in which -awakeFromNib is called is not defined. If you need exact ordering, then you should really approach it programmatically.
I've done the configuring code in the -(void)layoutSubviews method as
my -initwithFrame not get called
UIView has two designated initializers. When the view is loaded from a nib, -initWithCoder: is called instead of -initWithFrame:. You can put initialization code in that method, or put it in a common initialization method that you call from both initializers.
Is it right to do our initialization in the -layoutSubViews as there
is a chance for this method to get called another time.
That is, indeed, the problem with using -layoutSubviews for initialization: it may be called more than once, and not always at the beginning of your view's lifetime. Better to use the initialization methods.
I am creating a customView and for example, would like to set the text color of the label and initialise the text of the label.
The initWithFrame is the generic function.
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
I have tried initialising the label in the initWithFrame, but it doesn't work. But when I do it in awakeFromNib, it allows me to set the text color but not the text(this value comes from a dictionary)
-(void)awakeFromNib
{
//setting of the label textcolor
}
What would be the correct way to initialise the color and text of labels and other stuff?
Need some suggestions and guidance...
Edit:
-(void)viewDidLoad
{
[self updateViewWithDictionary:dictPassed];
}
Something like this?
What I do in some project's is expose a public method like so:
- (void)updateViewWithDictionary:(NSDictionary *)confDictionary;
In that dictionary I pass the parameters I want, and inside the UIView's subview I update it according to what I want.
Edit 1:
Read wrongly your question, sorry. You have a custom UIView that you would like to be updated when your UIViewController starts, or when you actually use it. So you should have something like this:
#interface MyView : UIView
{
}
- (void)updateViewWithDictionary:(NSDictionary *)confDictionary;
#end
And from your viewDidLoad:
-(void)viewDidLoad
{
[self.customView updateViewWithDictionary:dictPassed];
}
I am wanting to create a custom UIView class that will show a dynamic number of UISegmentedControl objects depending on some input. For example, if a client has 5 products in their cart, the UIView should generate 5 UISegmentedControl objects that I will then link with each item.
The problem I am having is getting this to work in a UIView. Here is what I have done so far. I am successfully able to create a UISegmentedControl object and display it programmatically within my main UIViewController. I don't get any display when adding it to my UIView class. Here is the implementation code for the UIView class:
#import "ajdSegmentView.h"
#implementation ajdSegmentView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
NSArray *itemArray = [NSArray arrayWithObjects:#"Yes", #"No", nil];
UISegmentedControl *button = [[UISegmentedControl alloc] initWithItems:itemArray];
button.frame = CGRectMake(35,44, 120,44);
button.segmentedControlStyle = UISegmentedControlStylePlain;
button.selectedSegmentIndex = 1;
[self addSubview:button];
}
return self;
}
#end
I created a new UIView object via Storyboard and placed it inside the UIViewController scene. I made sure to set the class from the generic UIView class to my new custom class. I added and outlet for the UIView in my UIViewController class. Here is the code inside the implementation of UIViewController:
#import "ajdViewController.h"
#interface ajdViewController ()
#end
#implementation ajdViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.segmentView = [[ajdSegmentView alloc] init];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
That's all I have tried. I have been searching through a lot of pages and trying to implement this without asking here, but I seem to be looking in the wrong places.
First you need to check ajdSegmentView is UIVIew or UIViewController. It is fine if it is UIView. If it is type of UIViewController then you need to add this line while adding Segment.
[self.view addSubview:button];
In place of:
[self addSubview:button];
And One more thing You forget to add this View to your main after allocating so You can declare like this:
objajdSegmentView = [[ajdSegmentView alloc] init];
[self.view addSubview:objajdSegmentView.view];
I have just added this thing. i got result like this way.
Hope this will work for you.
You're initializing your custom view using the init method, but your initialization for ajdSegmentView is in your initWithFrame: method (which in your case is not getting called).
So replace:
self.segmentView = [[ajdSegmentView alloc] init];
with:
// Change the frame to what you want
self.segmentView = [[ajdSegmentView alloc] initWithFrame:CGRectMake(0,0,100,40)];
Also don't forget to add your view to the view controller's view also.
[self.view addSubview:self.segmentView];
Unless this view is being created with interface builder, in which case you will need to override initWithCoder: in your ajdSegmentView class.
I'm not familiar with Storyboard though, so maybe I'm missing something, but in a standard scenario what I said above will solve your problem.