Setting the properties of items in an customview in iOS - ios

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];
}

Related

Subclassing an UIButton: custom behaviour on "touchUpInside"

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

iOS: Dynamic Creation of UISegmentedControl within UIView

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.

initWithFrame: method in HGKOptionPanel Library

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

Can't do integer == comparison

So I have a method that sets an integer: -(void)setcurrentviewfromint:(int)currentint{ It is in a class called MyView. From my viewDidLoad method, I call it, and set it too 1:
currentview is of type int, created in my header file
- (void)viewDidLoad
{
[super viewDidLoad];
MyView *myview = [[MyView alloc]init];
[myview setcurrentviewfromint:1];
}
Then, in MyView.m, I have these classes:
-(void)setcurrentviewfromint:(int)currentint{
currentview = currentint;
NSLog("currentviewis:%d",currentview);
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect {
NSLog(#"drawRectCalled");
if (currentview == 1) {
NSLog(#"do something here");
}
}
}
But the debugger prints out:
2012-07-18 18:02:44.211 animation[76135:f803] currentviewis:1
2012-07-18 18:02:44.223 animation[76135:f803] drawRectCalled
But doesn't print "do something here". Any ideas why currentview doesn't equal 1?
First, about your question.
What datatype is currentview?
Second, it looks like your NSLog in setcurrentviewfromint: never gets called. If it was called, youd see "currentviewis:1" so make sure that is linking up correctly.
And, I must say, camel-case! Your method names are all lowercase and it's hard to read. :)
The issue is that the MYView you are setting is not the one you are reading currentView from.
In viewDidLoad you are creating a local variable myView and then setting its current view and then this myView becomes a memory leak as nothing points to it.
Assuming that MyView is the class the viewDidLoad is on and that currentview is an int attribute of that class (although the why is the method not setcurrentview:) . I would expect the code to be more like
- (void)viewDidLoad
{
[super viewDidLoad];
[self setcurrentviewfromint:1];
}
Thus setting the current view in itself
And as others state please use the Objective C standard of CamelCase

When can I start using properties set using UIAppearance?

I have some custom appearance properties in my view class (a descendant of UIView). I want to customize the view appearance according to these properties, but I can’t do that inside the initializer, since the values set using [[MyClass appearance] setFoo:…] aren’t in effect at that point:
#interface View : UIView
#property(strong) UIColor *someColor UI_APPEARANCE_SELECTOR;
#end
#implementation View
#synthesize someColor;
// Somewhere in other code before the initializer is called:
// [[View appearance] setSomeColor:[UIColor blackColor]];
- (id) initWithFrame: (CGRect) frame
{
self = [super initWithFrame:frame];
NSLog(#"%#", someColor); // nil
return self;
}
#end
They are already set in layoutSubviews, but that’s not a good point to perform the view customizations, since some customizations may trigger layoutSubviews again, leading to an endless loop.
So, what’s a good point to perform the customizations? Or is there a way to trigger the code that applies the appearance values?
One possible workaround is to grab the value directly from the proxy:
- (id) initWithFrame: (CGRect) frame
{
self = [super initWithFrame:frame];
NSLog(#"%#", [[View appearance] someColor); // not nil
return self;
}
Of course this kills the option to vary the appearance according to the view container and is generally ugly. Second option I found is to perform the customizations in the setter:
- (void) setSomeColor: (UIColor*) newColor
{
someColor = newColor;
// do whatever is needed
}
Still I’d rather have some hook that gets called after the appearance properties are set.
Why not wait until
- (void)willMoveToSuperview:(UIView *)newSuperview {
[super willMoveToSuperview:newSuperview];
if (newSuperview) {
... code here ...
}
}
if it's giving you trouble?
I believe UIAppearance properties are applied to a view when it is being added into a view hierarchy. So presumably you could access the set properties in UIView didMoveToSuperview.
Caveat: I am using Swift 2, so not sure about earlier versions of Swift / Objective-C. But I have found that didMoveToSuperview() will not work. The properties are available in layoutSubviews(), but that's not a great place to do anything like this (since it can be called more than once). The best place to access these properties in the lifeCycle of the view I have found is didMoveToWindow().
I would have thought that viewDidLoad would be best if it's a one-time thing. Otherwise, viewWillAppear.
EDIT:
If you want to do it in the view, and not it's controller then I would create a custom init for the view along the lines of:
-(id) initWithFrame:(CGRect) frame andAppearanceColor:(UIColor)theColor;
thereby passing the colour into the view at creation time.

Resources