Adding item to a subview from a external class - iphone

I've created a UIView and can add things to it by using [self.topView addSubview:image]; Now I am importing a class to create a calendar which has a heap of buttons. I could put it in the same class and say [self.topView addSubview:button] but if its in another class how do I add it to the subview of the class that owns it? Hope that makes sense...

You need a reference in your external class to the class that owns the view (call it the "owner class"), and presumably write a method in your owner class to add a passed-in view to your chosen subview. Something along the lines of:
- (void) insertSubview:(UIView*)newView {
if (newView) [self.topView addSubview:newView];
}
Setting up the reference can be done a number of ways, so I'll leave that one to you.

Related

how to give two different class reference to single UIView?

I want to implement two functionalities as color filling and view magnifying in my app. But the problem is that i can't be able to implement these two functionalities at same time. Because i have to specify two difference class reference for two functionalities to my UIView, which can't be possible.
In other words, I have one view and i have given class reference as UIView (for color function). But for magnify function , i have to give class reference as MagnifyingView to that view. So, it is not possible to implement these two functionalities at same time.
So how can i give UIView and ACMagnifyingView two different class reference to single UIView at different conditions?
How can i do this ?
Thanks.
Have you tried Categories? check this tutorial http://iphone-obsessed.blogspot.com.br/2010/05/tutorial-creating-class-categories-in.html
can you provide more information? maybe if you provide more info i could help you more
EDIT
How Categories work:
you have a UIView class and you want some methods to use that you repeat a lot. what do you do: you create a category of UIView and add this method to your category, like this:
file UIView+CustomView.h
#import <UIKit/UIKit.h>
#interface UIView (CustomView)
- (void)myCustomMethod;
#end
file UIView+CustomView.m
#import "UIView+CustomView.h"
#implementation UIView (CustomView)
- (void)myCustomMethod {
// Whatever you want to do with this UIView
}
#end
now, every time you need to use the myCustomMethod you just have to import UIView+CustomView.h and all UIView objects inside that class will have access to this method.
like this:
file MainViewController.m, header:
#import "UIView+CustomView.h"
file MainViewController.m, body, inside any method:
[myView myCustomMethod];
with this in mind i believe you could add your ACMagnifyingView as a subclass and this category to use your custom view

Two way relation for UIViewController

I have a container view controller say ContainerViewController and another UIViewController(PhotoViewcController) which i am adding as a childviewcontroller in ContainerViewController. So that message is forwarded from ContainerViewController to PhotoViewcController. But how can i use the two way relation in the parent child view controllers? so that message is passed form PhotoViewcController to ContainerViewController.
make a property in child class like this
#property (assign) id pDelegate;
and synthesize it, and when you go to child view controller, set the delegate as self before push/present as
childController.pDelegate = self;
now when you want to send the message, do this
if([self.pDelegate respndsToSelector:#selector(popedBackFromChild:)])
{
[self.pDelegate popedBackFromChild:<some object>];
}
tell me if you need further explanation
There are two ways that you can do this. Either define a protocol for it in the child class and define it in the parent class or you can post and notification and pass the necessary information as a dictionary. As #The Saad has told you, this is the best way you can define a protocol but notifications are easier to manage.
P.S. Parent class is the class where you will update the information and Child class will be providing it.

How to programmatically assign/replace an existing UITableView with a new one?

I have the following code to my UIViewController class implementation:
- (void)viewDidLoad {
CustomUITableView *customUITableView = [[CustomUITableView alloc] initWithFrame:self.view.frame];
[self.view addSubview:customUITableView];
[super viewDidLoad];
}
When I run the app, the table shows up just fine. There are two problems I have with this approach:
I lose the use of StoryBoard since the table is dynamically added to the view. I would like to arrange my view in StoryBoard and not have to manually tweak its position in code.
I also want the ability to swap between CustomUITableViews at runtime (if possible). For example, if I create a "CustomUITableView_Number2", can I simply decide which custom class I want to use for the table at runtime?
I know I can accomplish this in StoryBoard by assigning a custom class to the UITableView, but I want to see how far I can go using only code. My goal is to arrange the layout using StoryBoard, but assign the custom class I want at runtime.
Does anyone know if this is possible? Sample code would really help. Thank-you.
You could load a regular UITableView from interface builder and then initialize a CustomUITableView with the parameters you are interested in from the UITableView.
- (void)viewDidLoad {
//Your tableView was already loaded
CustomUITableView *customUITableView = [[CustomUITableView alloc] initWithFrame:tableView.frame style:tableView.style];
customUITableView.backgroundColor = tableView.backgroundColor;
//...
//... And any other properties you are interested in keeping
//...
[self.view addSubview:customUITableView];
[super viewDidLoad];
}
This approach will work if you make sure to specify each property you think you would modify in interface builder. Just make sure to remove the UITableView that was loaded via the nib after you copy the properties over.
sure you can replace the table.
something as simple as
Class MyTableClass = NSClassFromString(#"WhateverClass");
id newTableView = [[MyTableClass alloc] init];
[newTableView performSelector:#selector(someSel:)];
make sure you set your datasource and delegate and whatever properties from the original nib instantiated view first, then
you could then set your local tableview property to this new object and as long as the ivar has a proper cast you could call methods on it without resorting to runtime calls like above.
You can also dig into the obj-c runtime if you wanted to do it in a different way.
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html

need multiple inheritance in Objective C

I want to implement a movable UIView class (view moves when you touch on it and move your finger), e.g.:
#interface MovableView : UIView {
some members;
}
-touchesBegan;
-touchesMoved;
#end
How can I apply this code to UILabel, UIButton etc without multiple inheritance? In C++, I'd do it like this (with UIView as a virtual base to MovableView):
struct MovableLabel : UILabel, MovableView {};
Categories are offered as an alternative to multiple inheritance but I definitely don't want to extent UIView using categories because that would apply to all views in my application. I only want some of my views to be movable.
My current strategy to avoid code duplication is putting MovableView code in a header file and including it everytime I need some class to use it. Besides that I have to add members of MovableView to whatever class I am writing. It is pure code ugliness but better than copy/pasting code all over my project.
Does anyone have any other ideas to get around this Objective C limitation [of not having multiple inheritance]?
Thanks,
Altan
Objective-C won't let you do this mixin inheritance thing, except by adding the same category to each of the classes you care to augment. And then, you won't get extra instance variables.
For your specific problem, I might approach it by designing MovableView as a container class that was just an object that has a child view (UILabel, UIButton, etc) that you want to move as its subview.
Categories would not help anyway because replacing the real touchesBegan method on UIButton would be pretty bad... you can't call [super] from a category.
Another solution would be to inject a method into those class definitions with something like:
Method origMethod = class_getClassMethod([UIButton class], #selector(touchesBegan));
Method newMethod = class_getClassMethod([TemplateClass class], #selector(replacementTouchesBegan));
method_exchangeImplementations(origMethod, newMethod);
But that's pretty fiddly. Although if it's really where you want to go, it's worth looking into...
What I would do is make a MovableView class that inherits from UIView, and simply add whatever you want movable as a subview of that view (which I think might be slightly different than what quixoto was saying, my apologies if not). It gets to respond to touches first and passes along whatever it doesn't need to the next responder... no need to build up a special class with a single subview. Then in IB you can just place these movable views wherever and put things inside of them.
In general compositional techniques like this are very handy across UIKit rather than modifying core classes.

How can one address controls dynamically in obj-c?

For instance I have created a view with 50 sequential buttons named btn1-btn50. If I want to address these buttons and make some changes to them in a loop how can I address the controls with a string name?
The typical way to get a view in a hierarchy is to call [parentView viewWithTag:] to get the view. If you give the buttons tag values from 1 to 50 you can use that to access the buttons.
If for some reason you need strings, you will have to create a custom subclass of UIButton that has a name member, assign a name to that member, then later iterate through the view hierarchy searching for an instance of your custom class with a name matching your search criteria.
If you have given them a tag, you can access them conveniently using -viewWithTag: on the parent view.
You have no guarantee that these buttons are laid out in memory sequentially, so trying to use pointer arithmetic is probably out. But you can get all the subviews of an NSView with -subviews, and just do something with the NSButtons:
for (NSView *view in [theView subviews]) {
if (![view isKindOfClass:[NSButton class]]) continue;
/// you got a button!
}
In your View Contoller add an NSMutableDictionary *buttonViews property. In your viewDidLoad method, add each button to buttonViews using the name string as the key and the button as the object. You will have to use viewWithTag: already discussed to obtain the views. Now you can locate the button using the string and benefit from the collection methods and fast enumeration. Apple's documentation for Interface Builder indicates that the "name" in IB is used to assist identifying objects in IB which is helpful for translation.