Go Back   MacRumors Forums > Apple Systems and Services > Programming > iPhone/iPad Programming

Reply
 
Thread Tools Search this Thread Display Modes
Old Jan 6, 2011, 12:38 PM   #1
StarLion
macrumors newbie
 
Join Date: Jan 2011
running in circles with globals

(Yay. More newbishness.)

Okay so, after the headaches of running around trying to stuff square pegs into round holes, i downloaded one of Apple's sample codes (MultipleDetailViews) and started jamming my stuff into their templates instead.

I've run into a slight issue though.

RootViewController is handling the item selection, as it should, and is doing it in this manner:
Code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    
    /*
     Create and configure a new detail view controller appropriate for the selection.
     */
    curfile = [[[indexItems objectAtIndex:indexPath.section] objectAtIndex:indexPath.row] objectForKey:@"filename"];
    UIViewController <SubstitutableDetailViewController> *detailViewController = nil;

    if (curfile != @"Calculator") {
        FirstDetailViewController *newDetailViewController = [[FirstDetailViewController alloc] initWithNibName:@"FirstDetailView" bundle:nil];
        detailViewController = newDetailViewController;
    } else {
        SecondDetailViewController *newDetailViewController = [[SecondDetailViewController alloc] initWithNibName:@"SecondDetailView" bundle:nil];
        detailViewController = newDetailViewController;
    }

    // Update the split view controller's view controllers array.
    NSArray *viewControllers = [[NSArray alloc] initWithObjects:self.navigationController, detailViewController, nil];
    splitViewController.viewControllers = viewControllers;
    [viewControllers release];
    
    // Dismiss the popover if it's present.
    if (popoverController != nil) {
        [popoverController dismissPopoverAnimated:YES];
    }

    // Configure the new view controller's popover button (after the view has been displayed and its toolbar/navigation bar has been created).
    if (rootPopoverButtonItem != nil) {
        [detailViewController showRootPopoverButtonItem:self.rootPopoverButtonItem];
    }

    [detailViewController release];
}
Which works fine.
But; I need to put information into the textarea (UITextView *textarea) of the FirstDetailViewController instance, based on the curfile variable.
I tried detailViewController.textarea.text = @"Some text", but was told that I couldnt do that 'in something not a structure or union'. Whatever that means.

FirstDetailViewController obviously doesnt have access to the curfile variable at runtime, and has no way of knowing which item was selected from the menu.

What am I missing here?
StarLion is offline   0 Reply With Quote
Old Jan 6, 2011, 05:32 PM   #2
dejo
Moderator
 
dejo's Avatar
 
Join Date: Sep 2004
Location: The Centennial State
Quote:
Originally Posted by StarLion View Post
I tried detailViewController.textarea.text = @"Some text", but was told that I couldnt do that 'in something not a structure or union'. Whatever that means.
Does detailViewController have a textarea property?
__________________
dejo is online now   0 Reply With Quote
Old Jan 7, 2011, 09:22 AM   #3
StarLion
Thread Starter
macrumors newbie
 
Join Date: Jan 2011
It did, but eventually it dawned on me that i managed to forget i could call functions with parameters lol.

so RootViewController.m now calls
Code:
        detailViewController = newDetailViewController;
		[detailViewController settext:curfile];
with FirstDetailViewController now containing the function
Code:
- (void)settext:(NSString *)curfile {
   	NSString *quack2=[[NSBundle mainBundle] pathForResource:curfile ofType:@"txt"];
	NSString *quack=[[NSString alloc] initWithContentsOfFile:quack2];
    textarea.text = quack;
}
(Using the quacks for breakpoint checking.)

The function fires.
Quack gets set correctly.
textarea is linked in IB. (and saved)
But the display doesn't show the changed text.
I'm confused.
StarLion is offline   0 Reply With Quote
Old Jan 7, 2011, 10:43 AM   #4
dejo
Moderator
 
dejo's Avatar
 
Join Date: Sep 2004
Location: The Centennial State
Quote:
Originally Posted by StarLion View Post
It did, but eventually it dawned on me that i managed to forget i could call functions with parameters lol.
Not sure you needed to abandon troubleshooting that error, but fine...

Quote:
Originally Posted by StarLion View Post
so RootViewController.m now calls
Code:
        detailViewController = newDetailViewController;
		[detailViewController settext:curfile];
with FirstDetailViewController now containing the function
Code:
- (void)settext:(NSString *)curfile {
   	NSString *quack2=[[NSBundle mainBundle] pathForResource:curfile ofType:@"txt"];
	NSString *quack=[[NSString alloc] initWithContentsOfFile:quack2];
    textarea.text = quack;
}
(Using the quacks for breakpoint checking.)

The function fires.
Quack gets set correctly.
textarea is linked in IB. (and saved)
But the display doesn't show the changed text.
I'm confused.
What are you doing to retain the value assigned to quack? Since textarea is a property, (my apologies if I'm sounding like a broken record on this lately) you should assign it using the synthesized accessors and not reference the ivar that backs it directly.

Here's a tip: if you have property, name the ivar that backs it with a leading underscore, as in the following code:
Code:
@interface SampleAppViewController : UIViewController {
	UITextView *_textarea;
}
@property (nonatomic, retain) IBOutlet UITextView *textarea;

@end

@implementation SampleAppViewController

@synthesize textarea = _textarea;

...
Then when you try to do something like:
Code:
textarea.text = quack;
you will get a compile-time error, since there is no ivar named textarea.
__________________
dejo is online now   0 Reply With Quote
Old Jan 7, 2011, 02:45 PM   #5
StarLion
Thread Starter
macrumors newbie
 
Join Date: Jan 2011
Well i dont get an error. The program runs, it just doesnt do what i think it's supposed to.

Quack doesnt need to (and shouldnt) be retained - it's not used anywhere else, and is re-assigned every time the script fires, making retaining it rather silly, unless i'm missing something here.
.h
Code:
@interface FirstDetailViewController : UIViewController <SubstitutableDetailViewController> {

    UIToolbar *toolbar;
	UITextView *textarea;
}

@property (nonatomic, retain) IBOutlet UIToolbar *toolbar;
@property (nonatomic, retain) IBOutlet UITextView *textarea;

@end
.m
Code:
@synthesize toolbar,textarea;
Forgive me for being somewhat dense... but why would I -want- to give myself a compile-time error by changing the reference to textarea, when leaving it as is should work?

Why do you say textarea is a property? It's not a reserved word of any class relating to UITextView, and nothing stops this code from working properly when i do this in a regular view app...

Edit: I modified the synthesis line to be @synthesize toolbar,textarea = _textarea; and the appropriate line to _textarea.text = quack; . No change at all in the program.

Last edited by StarLion; Jan 7, 2011 at 03:02 PM.
StarLion is offline   0 Reply With Quote
Old Jan 7, 2011, 03:13 PM   #6
dejo
Moderator
 
dejo's Avatar
 
Join Date: Sep 2004
Location: The Centennial State
Sorry, I'm confused. Just ignore what I said.

EDIT:

Anyways, seems to me that you should verify that textarea is not nil before you try to assign its text.
__________________

Last edited by dejo; Jan 7, 2011 at 03:50 PM.
dejo is online now   0 Reply With Quote
Old Jan 8, 2011, 08:30 AM   #7
StarLion
Thread Starter
macrumors newbie
 
Join Date: Jan 2011
You're correct, it is coming up as 0x0 when i do:
Code:
	UITextView *temp=textarea;
(temp = 0x0)

... but why? it's linked in IB, part of the interface in the header, propertied, synthesized....
StarLion is offline   0 Reply With Quote
Old Jan 8, 2011, 11:43 AM   #8
dejo
Moderator
 
dejo's Avatar
 
Join Date: Sep 2004
Location: The Centennial State
It has not yet been assigned to the property at the time you are referencing it. View loading fun, I like to call it. Somehow you need to delay the setting of the text, in order to allow textarea to become non-nil.
__________________
dejo is online now   0 Reply With Quote
Old Jan 8, 2011, 05:54 PM   #9
PhoneyDeveloper
macrumors 68030
 
PhoneyDeveloper's Avatar
 
Join Date: Sep 2008
In general it's bad to directly access views that belong to one view controller from some other object. The fact that you're forced to make public properties for all your outlets makes you think that it's ok to do this.

As dejo points out the views aren't loaded until the nib is loaded. The correct way to solve this is to add a string property to the view controller, and then use the value of that property in viewDidLoad to set the text of your text view. The case where your views are unloaded due to a memory warning will be solved in that case while setting the text of the view from outside the class will not work correctly.
PhoneyDeveloper is offline   0 Reply With Quote
Old Jan 9, 2011, 08:33 AM   #10
StarLion
Thread Starter
macrumors newbie
 
Join Date: Jan 2011
Yay for fun.

I did pretty much exactly what Phoney said...

(cfile is a declared/synthesized/retained NSString)
Code:
- (void)settext:(NSString *)curfile {
	cfile = curfile;
}

- (void)viewDidLoad {
	[super viewDidLoad];
    textarea.text = [[NSString alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:cfile ofType:@"txt"]];
}
works as intended now Thank you both for your patience!
StarLion is offline   0 Reply With Quote
Old Jan 9, 2011, 12:07 PM   #11
PhoneyDeveloper
macrumors 68030
 
PhoneyDeveloper's Avatar
 
Join Date: Sep 2008
Glad it's working. Couple comments:

If cfile is already a property then I don't understand why you need the settext setter.

You're leaking memory on the line where you assign the string to textarea.text.
PhoneyDeveloper is offline   0 Reply With Quote
Old Jan 14, 2011, 10:28 AM   #12
StarLion
Thread Starter
macrumors newbie
 
Join Date: Jan 2011
Quote:
Originally Posted by PhoneyDeveloper View Post
Glad it's working. Couple comments:

If cfile is already a property then I don't understand why you need the settext setter.

You're leaking memory on the line where you assign the string to textarea.text.
Okay... the setter is there because viewDidLoad doesnt take parameters? I'm confused here. The function thats being fired is inside RootViewController, which then creates an instance of the FirstDetailViewController. The FirstDetailViewController has a property, cfile, but thats blank at instantiation. I cant use detailViewController.cfile = curfile because that throws the 'not in a union or structure' error. So how would i set a property of an object from another object without that structure?

No idea where i'm leaking memory in assigning the string... so no idea how to fix it.

Additionally: Now i need to do things in reverse. I have a button in the toolbar of one of my views (Which is now called InfoViewController) that needs to go up a level to the RootViewController and fire the view-changing command... is that even possible?
StarLion is offline   0 Reply With Quote
Old Jan 14, 2011, 10:42 AM   #13
dejo
Moderator
 
dejo's Avatar
 
Join Date: Sep 2004
Location: The Centennial State
Quote:
Originally Posted by StarLion View Post
Okay... the setter is there because viewDidLoad doesnt take parameters? I'm confused here. The function thats being fired is inside RootViewController, which then creates an instance of the FirstDetailViewController. The FirstDetailViewController has a property, cfile, but thats blank at instantiation. I cant use detailViewController.cfile = curfile because that throws the 'not in a union or structure' error. So how would i set a property of an object from another object without that structure?
What is the class of your detailViewController object when you try to make this assignment? Is it a FirstDetailViewController or a UIViewController?
__________________
dejo is online now   0 Reply With Quote
Old Jan 14, 2011, 10:46 AM   #14
PhoneyDeveloper
macrumors 68030
 
PhoneyDeveloper's Avatar
 
Join Date: Sep 2008
There's no reason why you shouldn't be able to set the value of a public property from another class.

Code:
detailViewController.cfile = curfile;
Should work. If you get compiler errors you should show us the header file and the code that creates the object and sets the property.
PhoneyDeveloper is offline   0 Reply With Quote
Old Jan 15, 2011, 04:05 PM   #15
StarLion
Thread Starter
macrumors newbie
 
Join Date: Jan 2011
Code:
    UIViewController <SubstitutableDetailViewController> *detailViewController = nil;

    if (curfile != @"Calculator") {
        InfoViewController *newDetailViewController = [[InfoViewController alloc] initWithNibName:@"InfoView" bundle:nil];
        detailViewController = newDetailViewController;
		[detailViewController settext:curfile];
so it's a UIViewController pointer that implements the SubstituteableDetailViewController protocol (at least, thats how i read that line. I could be wrong)

SubstitutableDetailViewController is defined in RootViewController.h as:
Code:
@protocol SubstitutableDetailViewController
- (void)showRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem;
- (void)invalidateRootPopoverButtonItem:(UIBarButtonItem *)barButtonItem;
- (void)settext:(NSString *)curfile;
@end
InfoViewController is defined by InfoViewController.h as
Code:
#import <UIKit/UIKit.h>
#import "RootViewController.h";

@interface InfoViewController : UIViewController <SubstitutableDetailViewController> {

    UIToolbar *toolbar;
	UITextView *textarea;
	NSString *cfile;	
}

@property (nonatomic, retain) IBOutlet UIToolbar *toolbar;
@property (nonatomic, retain) IBOutlet UITextView *textarea;
@property (nonatomic, retain) IBOutlet NSString *cfile;

-(IBAction) loadCalc:(id) sender;
-(void) settext:(NSString *) curfile;

@end
(loadCalc is the function that is tied to the new button that needs to somehow change the view of the RootViewController. Currently not working.)

EDIT: Looking at it, i have no idea why I IBOutlet'd cfile, since... it's not tied to an IB object.

Last edited by StarLion; Jan 15, 2011 at 05:24 PM.
StarLion is offline   0 Reply With Quote
Old Jan 15, 2011, 09:10 PM   #16
dejo
Moderator
 
dejo's Avatar
 
Join Date: Sep 2004
Location: The Centennial State
So, do you understand why detailViewController has no cfile property?
__________________
dejo is online now   0 Reply With Quote
Old Jan 16, 2011, 10:17 AM   #17
StarLion
Thread Starter
macrumors newbie
 
Join Date: Jan 2011
Well it makes sense that it has no cfile property, so using the setter was appropriate.... so i'm not sure why i was told not to use the setter :P

Last edited by StarLion; Jan 16, 2011 at 10:39 AM.
StarLion is offline   0 Reply With Quote
Old Jan 16, 2011, 11:46 AM   #18
dejo
Moderator
 
dejo's Avatar
 
Join Date: Sep 2004
Location: The Centennial State
Quote:
Originally Posted by StarLion View Post
Well it makes sense that it has no cfile property...
And that reason is? Sorry if I'm pushing so hard on this but I'm trying to get you to explain why it makes sense rather than just agreeing. Then, once you do, you might also see that you already have a variable whose class does have a cfile property that you can set through its synthesized accessor.
__________________
dejo is online now   0 Reply With Quote

Reply
MacRumors Forums > Apple Systems and Services > Programming > iPhone/iPad Programming

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Similar Threads
thread Thread Starter Forum Replies Last Post
Strange rainbow circles in Mail AverySullivan OS X Mavericks (10.9) 0 Nov 24, 2013 02:43 PM
iPad: Thinking myself in circles, iPad 4 or 5? (from a 3) thefredelement iPad 10 Oct 22, 2013 05:34 PM
The circles are BAD TASTE Deasnutz iOS 7 6 Aug 7, 2013 01:33 AM
What are these circles? (pic) agkm800 Community Discussion 4 Mar 14, 2013 01:59 AM
Going in circles wrz0170 iCloud and Apple Services 4 Jun 11, 2012 06:07 AM

Forum Jump

All times are GMT -5. The time now is 12:44 PM.

Mac Rumors | Mac | iPhone | iPhone Game Reviews | iPhone Apps

Mobile Version | Fixed | Fluid | Fluid HD
Copyright 2002-2013, MacRumors.com, LLC