How do i create a UITextView in main UIView from a UIButton Within UIPopover? - uiviewcontroller

I'm trying to create a UITextView in my Main UIViewController when a UIControlEventTouchUpInside happens with my UIButton which is in a UIPopoverController.
I tried to use a delegate protocol to allow my button to be referenced within the Main viewcontroller.m but I don't think I have been doing it right. I will also mention I've created the UIButton and UITextField programmatically in a UIView subclass for the UIPopover.

The view controller that you display in the UIPopoverController should look something like this:
#interface MyViewControllerForPopover : UIViewController
#property (weak) UIViewController *viewControllerInWhichCreateTheTextField;
...
#end
Meaning that you could keep a weak reference to the view controller in which you want to add the text field. The button you generated in this MyViewControllerForPopover could do something like:
- (void)createTextViewInConnectedViewController:(id)sender {
UITextField *myTextField = ...;
[self.viewControllerInWhichCreateTheTextView.view addSubview:myTextField];
}
The key concept is that you want to have a weak reference (to avoid retain cycle) to the view controller you wish to alter. Even better if that view controller has a method to actually add the text field itself. Hope it helps!

Related

how to make UIViewController Title show up on titleView in UINavigationController?

I thought, and I may be wrong, without doing anything, the titleView of UINavigationController default to the title of the UIViewController.
Mine is not the case and I wonder why?
I set the title of the UIViewController in the story board to #"Nearby". I confirm that it's indeed the title in viewDidLoad
- (void)viewDidLoad
{
PO(self.title);
PO(self.navigationController.title);
Produce
self.title: Nearby
self.navigationController.title: (null)
I think I can programatically force my way and set the titleView to a UILabel with my title but I am not sure that would be the right way to do it.
I wonder why self.navigationController.title is not automatically set to self.title? If so when should it be set and where?
By the way, I added this line:
self.navigationController.title=self.title;
That doesn't help.
Update: Changing the NavigationItem Title Works. But that's awkward. Also how do I change that programatically?

Coding a custom navigationItem.rightBarButtonItem once and having it reused in both UITableViewControllers and UIViewControllers?

I have successfully added a rightBarButtonItem to my navigationBar, but I would prefer to only have the code to do so show up once rather than once per type of ViewController. Here's my current setup:
-->TVC
|
NVC--->TVC--->TVC--->VC
So far I've subclassed UITableViewController and moved my code for adding the button into my subclass. All 3 of my TableViewControllers are set to that subclass and it works perfectly.
However now I need my lone ViewController to also show the button, but I don't know how to accomplish this without duplicating the code from my TVC subclass. Is subclassing the right answer or do I need a different approach?
Edits:
#CarlVeazey - Sure, I call it from the viewDidLoad function.
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"BETA" style:UIBarButtonItemStylePlain target:self action:#selector(betaPressed)];
Do a pull-up refactor into a UIViewController category. If your project already has one, just add this code there, otherwise press cmd-N in Xcode to create a new file and choose "Objective-C Category" and enter UIViewController in the "Category On" field.
In the interface add this method declaration:
- (void)onfConfigureRightNavigationBarButton;
And in the implementation add this method implementation:
- (void)onfConfigureRightNavigationBarButton
{
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"BETA"
style:UIBarButtonItemStylePlain
target:self
action:#selector(betaPressed)];
}
Then in any UIViewController subclass you can import your category header and call this method. You may also wish to add to your category an empty implementation of betaPressed:.
BTW, ONF is the prefix I use for non-work coding so use whatever prefix already is in your project, or none at all if you're not concerned with category name collisions.

instance variable in NSManagedObject class acts like a class variable?

IOS 5 only, with ARC. In my Core Data model class:
// Planet.h //
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#interface Planet : NSManagedObject
#property (nonatomic, retain) NSString *name;
#property (nonatomic, retain) NSNumber *diameter_km;
#property (nonatomic, retain) NSNumber *mass_kg;
-(void) setVisited:(BOOL)flag;
-(BOOL) isVisited;
#end
// Planet.m //
 
//#import "Planet.h"
#implementation Planet
 
#dynamic name;
#dynamic diameter_km;
#dynamic mass_kg;
 
BOOL visitedByHumans;       // not a core data entity; just an ivar
 
-(void)setVisited:(BOOL)flag {
    visitedByHumans = flag;
}
-(BOOL)isVisited {
    return visitedByHumans;
}
 
#end
I use MagicalRecord to create "Venus" and "Mars". In my view controller, I use labels and buttons to test the above. Testing shows that when I "visit" Mars, Venus also becomes visited. If I switch the ivar visitedByHumans into a non-Core-Data property, it works as expected. So I'm no longer 'stuck', but I want to understand the ivar thing.
vistedByHumans is not actually an ivar, but a global variable of your subclass Planet. So, any and every "planet" instance will appear to be visited regardless of which instance is actually visited. If you want to make it an actual ivar, you need to add a #property to your #interface much like name, diameter_km, and mass_kg (although, those three of course were generated for your models). e.g.:
#property (nonatomic,assign,getter=isVisited) BOOL visited;
and in your implementation:
#synthesize visited=visitedByHumans;
or just
#synthensize visited;
Since you appear to be using those methods (visited and setVisited:) anyhow, and not really directly accessing visitedByHumans.
Also, be sure to remove the line of code
BOOL visitedByHumans;
and the two method definitions isVisited and setVisited:. They will be generated for you when you #synthesize'd them.
It's impossible to be sure based on the information you've presented. Your description doesn't match the code-- despite what you say, visitedByHumans is most definitely not an instance variable in that code. This then makes me wonder what the code looked like back before you switched it away from using Core Data for visitedByHumans. Basically, you explain that the code wasn't working right when you were using Core Data, but then present entirely different code that doesn't actually use Core Data. I don't know what you were doing when you were trying to use Core Data for this property so I can't tell what you might have been doing wrong. If that declaration of visitedByHumans was in the code at that time, it was almost certainly screwing things up for you. Likewise, if you had setters in a managed object subclass that didn't call super's implementation, you'd get bad results. But if you want to know why your Core Data code wasn't working, paste that code, not some completely different code. Don't make people guess what you're up to when you ask for help.

Adding custom UIView to UIViewController in - (void)loadView (Objective-C)

I am taking a programming class (for noobs) and I need to create the UIViewController graphViewController's view programmatically (without interface builder).
The view is simple, it only consists of an IBOUtlet which is an instance of a UIView subclass called GraphView. graphView responds to several multitouch gestures for zooming and panning and what-not, but I handle all of that stuff in - (void)viewDidLoad.
I am doing just the creation of the self.view property and graphView in the code below:
- (void)loadView
{
UIView *gvcView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
self.view = gvcView;
[gvcView release];
GraphView *aGraph = [[GraphView alloc] initWithFrame:self.view.bounds];
self.graphView = aGraph;
[aGraph release];
}
When I run the app I do not see the graphView view in there. I just get a transparent view which shows the "My Universal App" label. I'm stumped. Please help.
Let me know if you need additional code.
Thanks!
Update: Big thanks to BJ Homer for the quick fix!
had to do the following:
add this line of code: [self.view addSubview:self.graphView]; at the end.
I was also getting this strange bug where graphView was showing up as completely black. This line of code fixed that: self.graphView.backgroundColor = [UIColor whiteColor];
And that's it!
Final question: Is the default background color black for a custom UIView?
Thanks again!
[self.view addSubview:self.graphView];
Until you add your graph view to a parent view, UIKit doesn't know where to display it. self.view is special, since that's the property that -loadView is supposed to set. That view will automatically be added to the screen. But your graph view is just floating off in the ether until you add it somewhere.

How to simplify code?

I'm building an very simple application and I would like to reduce the coding lines in it, and I would like to that by using one or two functions instead of 20.
The app displays 10 buttons. Each button has two buttons to display, both with the same action (sending an email) but each button has a different identity so it also has different email content. It works fine if I do a function for each button, but I know it's possible to simplify that, I just don't know how.
Can someone point me in the right direction? This is what I'm doing right now in my methods:
MFMailComposeViewController *controller1 = [[MFMailComposeViewController alloc] init];
controller1.mailComposeDelegate = self;
if ([MFMailComposeViewController canSendMail]) {
[controller1 setToRecipients:[NSArray arrayWithObjects: #"dev#company.com", nil]];
[controller1 setSubject:#"Button 1"];
[controller1 setMessageBody:#"The second option form button 1 was selected" isHTML:NO];
[self presentModalViewController:controller1 animated:YES];
}
[controller1 release];
Set a unique tag (see the tag property) for each button and check the tag of the sender in your one -sendEmail: method. All your buttons call that one method.