making header file than can be used anywhere for iphone - iphone

i want to make headerfile Rimage.h and m that i can use anywhere but i have a problem here
this is my
Rimage.h
#class Rahul_imageplaceCordinatesViewController;
#interface Rimage : NSObject {
Rahul_imageplaceCordinatesViewController *vc;
}
-(void)addImageSubViewAtX:(CGFloat)x atY:(CGFloat)y;
#property (nonatomic,copy) Rahul_imageplaceCordinatesViewController *vc;
+(void)check1;
#end
and this is my .m
#implementation Rimage
#synthesize vc;
/// this method let you have image with given X n Y
- (void)addImageSubViewAtX:(CGFloat)x atY:(CGFloat)y {
CGRect myImageRect1 = CGRectMake(x, y, 30.0f, 30.0f);
UIImageView *myImage1 = [[UIImageView alloc] initWithFrame:myImageRect1];
[myImage1 setImage:[UIImage imageNamed:#"status_finish.gif"]];
myImage1.tag = 1000;
myImage1.userInteractionEnabled = YES;
[self.view addSubview:myImage1];
}
now in my mainVC
i am calling like this
- (void)viewDidLoad {
Rimage *hw = [[Rimage alloc] init];
//[hw check1];
[Rimage check1];
[hw addImageSubViewAtX:160.0 atY:190.0];
}
but i cant display that image i dont know why :(

First I noticed is your #property you are making a "copy" of the ViewController in vc, I suspect that's a bad idea, you just want to assign or retain it.
Second, in addImageSubViewAtX, you have:
[self.view addSubview:myImage1];
But what is self there? It is the instance of Rimage. I'm guessing that perhaps you meant to add the image to the view in vc?? I don't see that vc is ever used in the code you provided so what is it for?
[vc.view addSubview:myImage1];

Related

How to make the changes with slider in viewcontroller 2 reflecting the changes in viewcontroller 1?

I do not know how to figure out the changes of the slider value with the view controller2 in the view controller 1. I think i am calling it correctly but the values are not getting passed to the view.
I put a slider in the nib file and when i change it's value the value of the rect height and width should change.
here's my //appdelegate.m
CGRect bounds = [self.window bounds];
KaleidoTab *view = [[KaleidoTab alloc] initWithFrame:bounds];
view.backgroundColor = [UIColor whiteColor];
KaleidoTabFirstViewController *vc = [[KaleidoTabFirstViewController alloc] init];
[vc setView: view];
KaleidoTabSecondViewController *vc2 = [[KaleidoTabSecondViewController alloc] init];
//[vc2 setView: view];
vc2.vc = vc;
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = #[vc, vc2];
self.window.rootViewController = self.tabBarController;
here's my //secondviewcontroller.h
#import <UIKit/UIKit.h>
#import "KaleidoTabFirstViewController.h"
#interface KaleidoTabSecondViewController : UIViewController {
IBOutlet UISlider *changeSize;
IBOutlet UILabel *label1; }
#property KaleidoTabFirstViewController *vc;
#property (nonatomic, retain) IBOutlet UISlider *changeSize;
- (IBAction) changeSizeSlider:(id)sender;
here's //secondviewcontroller.m
- (IBAction)changeSizeSlider:(UISlider *)sender
{
/// Change label to match slider's value
label1.text = [NSString stringWithFormat:#"%g", changeSize.value];
CGFloat changeSizeCont = changeSize.value;
((KaleidoTab *)vc.view).rect_width = changeSizeCont;
((KaleidoTab *)vc.view).rect_height = changeSizeCont;
}
kaleidotab.m has the methods for drawing the rectangles.
I synthesized the properties and everything is fine. I think there is something wrong with my firstviewcontroller object.
appreciate your time.
Thanks
Your code is using Java-like syntax rather than Objective-C syntax. You'll find it easier to diagnose issues like these if you adopt Objective-C's approach to OOP syntax:
// For getting property values
[objectName propertyName];
// For setting property values
[objectName setPropertyName];
A lot of how the iOS Framework works depends on following these conventions. Try changing your code to the following:
- (IBAction)changeSizeSlider:(UISlider *)sender
{
// Change label to match slider's value
[label1 text] = [NSString stringWithFormat:#"%g", [changeSize value]];
// Var for changing size
CGFloat changeSizeCont = [changeSize value];
// Log to the console so that we can confirm changeSizeCont is being set appropriately
NSLog(#"changeSizeCont = %d", changeSizeCont);
/* I'm not used to this current syntax, this may be what's going wrong
It's confusing to read, it should be clearer.
I understand that you are attempting to grab the 1st view controller and
change its view properties, I think you can drop the
((KaleidoTab *)vc.view).rect_width and replace it with
vc.view.rect_width
vc.view.rect_height
*/
((KaleidoTab *)vc.view).rect_width = changeSizeCont;
((KaleidoTab *)vc.view).rect_height = changeSizeCont;
// Log to the console so that we can confirm the rect_width and rect_height properties are receiving the change
NSLog("Current values for VC's view properties:");
NSLog(#"rect_width = %d", ((KaleidoTab *)vc.view).rect_width);
NSLog(#"rect_width = %d", ((KaleidoTab *)vc.view).rect_height);
}
This should help you head in the right direction. You'll be able to check on the console whether or not the property values are updating or not. If they are and the view isn't changing appropriately, you probably need to look at the life-cycle of the application and find out where you need to reload or update your view to reflect the changes of your view to the screen.

Adding NSObject to view - UIButton selector in NSObject causes crash

having a little issue in an ARC environment. Creating an NSObject that adds a view to a parent view - it's basically a 'popup class' that can handle some text and display it.
In a view controller it's instantiated..
CBHintPopup *popup = [[CBHintPopup alloc]init];
[popup showPopupWithText:#"test text" inView:self.view];
And the actual class files..
CBHintPopup.h
#interface CBHintPopup : NSObject {
}
-(void)showPopupWithText:(NSString *)text inView:(UIView *)view;
-(IBAction)closePopup;
#property (nonatomic, strong) UIView *popupView;
#property (nonatomic, strong) UIImageView *blackImageView;
#property (nonatomic, strong) UIButton *closeButton;
#end
CBHintPopup.m
#implementation CBHintPopup
#synthesize popupView,blackImageView, closeButton;
-(void)showPopupWithText:(NSString *)text inView:(UIView *)view {
//CREATE CONTAINER VIEW
self.popupView = [[UIView alloc]initWithFrame:CGRectMake((view.frame.size.width/2)-(225/2),-146,225,146)];
self.popupView.alpha = 0;
self.popupView.backgroundColor = [UIColor clearColor];
//CREATE AND ADD BACKGROUND
UIImageView *popupBackground = [[UIImageView alloc]initWithFrame:CGRectMake(0,0,225,146)];
popupBackground.image = [UIImage imageNamed:#"hintbackground.png"];
[self.popupView addSubview:popupBackground];
//CREATE AND ADD BUTTON
self.closeButton = [UIButton buttonWithType:UIButtonTypeCustom];
[self.closeButton addTarget:self action:#selector(closePopup) forControlEvents:UIControlEventTouchUpInside];
[self.popupView addSubview:self.closeButton];
//CREATE AND ADD LABEL
UILabel *popupTextLabel = [[UILabel alloc]initWithFrame:CGRectMake(22,25,176,93)];
popupTextLabel.text = text;
[self.popupView addSubview:popupTextLabel];
[view addSubview:self.popupView];
}
-(void)closePopup {
NSLog(#"HI");
}
Recieving the following once closePopup is called via pressing the button ('HI' is not printed)..
-[CBHintPopup performSelector:withObject:withObject:]: message sent to deallocated instance 0x246b2fe0
I've tried retaining the button in non-ARC and a load of other methods but simply having no luck. Probably something real simple but i can't nail it. I've removed all the setting up of the labels and images etc to save some space, so ignore alpha's etc.
Any help will be much appreciated, thanks for your time.
Have you implemented the constructor for CBHintPopup,since you have called the constructor
[[CBHintPopup alloc]init];
you have to implement the constructor method like this
in .m file of CBHintPopup
-(id)init{
if(self == [super init]){
// do some initialization here
}
return self;
}
I tried your code and found the crash you mentioned. I found a solution for fixing the crash.
I declared the CBHintPopup *popup; in the viewController's interface. And changed this line
CBHintPopup *popup = [[CBHintPopup alloc]init];
to
popup = [[CBHintPopup alloc]init];
Everything worked fine for me. But I couldn't find the reason behind this. Hope this will help you.
Found a fix for it - instead of CBHintPopup being an NSObject, i simply made it a sub-class of UIView and added self to the parent view (instead of self.popupView). I wouldn't really call this a 'fix' though - more of an alternative method. Surely an NSObject can add a UIView (with a UIBUtton) to a parent view with no problems? Is this a bug?
Make sure you are retaining the object for class CBHintPopup.
I think the crash is coming because object of CBHintPopup deallocates. And hence the action method is not found.

Delegate Being Sent To Wrong Class

I subclassed my navigation bar, making the title view clickable. When clicked, it will present another view controller. I am creating a protocol in the navigation bar, that will tell the navigation controller that the title view has been clicked. Here is how my navigation bar is defined:
NavigationBar.h:
#protocol NavigationBarDelegate;
#interface NavigationBar : UINavigationBar
{
id <NavigationBarDelegate> delegate;
BOOL _titleClicked;
}
#property (nonatomic, assign) id <NavigationBarDelegate> delegate;
#end
#protocol NavigationBarDelegate
#optional
- (void)titleButtonClicked:(BOOL)titleClicked;
#end
The delegate implements one optional method. The .m file is as follows:
NavigationBar.m:
#implementation NavigationBar
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
_titleClicked = 0;
}
return self;
}
- (void)drawRect:(CGRect)rect
{
self.tintColor = [UIColor colorWithRed:(111/255.f) green:(158/255.f) blue:(54/255.f) alpha:(255/255.f)];
UIImage *image = [UIImage imageNamed:#"titlelogo.png"];
UIButton *titleButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, image.size.width, image.size.height)];
titleButton.backgroundColor = [UIColor colorWithPatternImage:image];
[titleButton addTarget:self action:#selector(titleButton:) forControlEvents:UIControlEventTouchUpInside];
// self.navigationController.delegate = self;
[self.topItem setTitleView:titleButton];
[super drawRect:rect];
}
- (void)titleButton:(UIButton *)sender
{
_titleClicked = !_titleClicked;
[self.delegate titleButtonClicked:_titleClicked];
}
This creates a navbar with a logo and calls the titleButton method when the title button has been clicked. Everything is fine up till here and the navigation bar displays nicely.
In my RootViewController:
NavigationBar *navigationBar = [[NavigationBar alloc] initWithFrame:CGRectMake(0.0f, 0.0f, self.view.frame.size.width, 44.0f)];
navigationBar.delegate = self;
[self.navigationController setValue:navigationBar forKey:#"navigationBar"];
An implementation of titleButtonClicked is also there. When I click on the title view however, I get the following error: -[UINavigationController titleButtonClicked:]: unrecognized selector sent to instance
Why am I getting titleButtonClicked sent to UINavigationController? Is there something I need to do in my navigation controller? I am just using plain old UINavigationController. Do I need to subclass that too? If so, why?
EDIT:
Calling po self.delegate on line [self.delegate titleViewClicked:_titleClicked]; in NavigationBar.m yields the result below. How did the delegate change its type? How can I fix that?
(lldb) po self.delegate
(objc_object *) $1 = 0x07550170 <UINavigationController: 0x7550170>
As #idz said, the problem is with your:
#property (nonatomic, assign) delegete;
Don't you see that it's weird that you don't even have a:
#synthesize delegete;
That's because UINavigationBar already defines a delegate variable as idz said.
change your declaration to:
// use unsafe_unretained in ARC, not assign
#property (nonatomic, unsafe_unretained) myDelegete;
and of course
#synthesize myDelegate;
You have a clash/ambiguity between your delegate and UINavigationBar's delegate property. Rename your delegate to disambiguate them.

Adding stuff to UIView from other class

It's a very simple question, but I don't get it to work properly. I have the following setup:
iPhone app with a main controller (ViewController). I thought it would be better to export some parts of it to new files (better structure etc). So I created a new class, "ClassFile". This is what I want to do:
ViewController.m
// Launch function from other ViewController class
-(void)someWhereAtViewController {
ClassFile *Classinstance = [[ClassFile alloc] init];
UILabel *label = [Classinstance createLabel];
[Classinstance release];
}
ClassFile.m
// Do some stuff
-(UILabel *)createLabel {
// Create an UILabel "label"
[...]
// Now add the label to the main view
// Like this it clearly doesn't work, but how to do it?
[self.view addSubview:label]
// Return the label to the other class
return label
}
Thanks a lot for the input! As far as I know, everything in this dummycode works except adding the label to the main view.
-(UILabel *)createLabelInView: (UIView *)view {
// Create an UILabel "label"
[...]
// Now add the label to the main view
// Like this it clearly doesn't work, but how to do it?
[view addSubview:label]
// Return the label to the other class
return label
}
and then call it with:
// Launch function from other ViewController class
-(void)someWhereAtViewController {
ClassFile *Classinstance = [[ClassFile alloc] init];
UILabel *label = [Classinstance createLabelInView: self.view];
[Classinstance release];
}
It sounds like you want a "Category". A category is a way to add methods to existing classes, regardless of whether you have their source code or not.
So you have:
//ViewController.h
#interface ViewController : UIViewController {
}
#end
//ViewController.m
#import "ViewController.h"
#implementation ViewController
...
#end
You want another file with more methods for ViewController, correct? If so, then you'd do:
//ViewController+Extras.h
#import "ViewController.h"
#interface ViewController (Extras)
- (UILabel *)createLabel;
#end
//ViewController+Extras.m
#import "ViewController+Extras.h"
#implementation ViewController (Extras)
- (UILabel *)createLabel {
return [[[UILabel alloc] initWithFrame:CGRectMake(0,0,42,42)] autorelease];
}
#end
And then you'll be able to do:
//ViewController.m
#import "ViewController.h"
#import "ViewController+Extras.h"
#implementation ViewController
- (void)doStuff {
UILabel *newLabel = [self createLabel];
//do stuff
}
#end
For more information on Categories, check out the Documentation.

Programmatically Displaying a UILabel from another class

I'm re-factoring my code and would like to move a whole bunch of UILabels into another class to tidy things up a bit. I'm missing one puzzle piece to be able to do so though (or maybe I'm just tired lol) Anyway here's the simplified code showing my issue. Thanks in advance to anyone who helps :)
#interface MyClass : UIView {
UILabel *classLabel;
}
#property (assign) UILabel *classLabel;
#end
#implementation MyClass
#synthesize classLabel;
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
}
return self;
}
- (void)dealloc {[super dealloc];}
#end
#interface LabelTestViewController : UIViewController {
MyClass *myClassInstance;
UILabel *myLabel;
}
#property (assign) UILabel *myLabel;
#end
#implementation LabelTestViewController
#synthesize myLabel;
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// this shows a label on the screen as expected
myLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 50, 20)];
myLabel.text = #"Hello";
[self.view addSubview:myLabel];
[myLabel release];
// this doesn't show anything on the scree
myClassInstance = [MyClass new];
[myClassInstance drawRect:CGRectMake(10, 50, 50, 20)]; // I suspect I need to call a different method, just don't know which one. initWithFrame is what I used at the time of creation of the label in the previous working scenario. is there an equivalent?
myClassInstance.classLabel.text = #"Goodbye";
[self.view addSubview:myClassInstance.classLabel];
}
- (void)didReceiveMemoryWarning {[super didReceiveMemoryWarning];}
- (void)viewDidUnload {}
- (void)dealloc {[super dealloc];}
#end
A couple of things:
1) You should never call drawRect directly. Instead, call setNeedsDisplay or setNeedsDisplayInRect. See the Cocoa Drawing Guide or the UIView Class Reference for more info.
2) But that may not be source of your problem. From your code, it is difficult to tell what ends up in classLabel after you are done setting it up, but I expect it's not what you need. In particular, it needs a frame. I would suggest setting a CGRect variable to myClassLabel.frame and seeing what you end up with.