Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
NoDamage
Dec 2, 2000

carry on then posted:

Thanks both for slogging through that wall of text, I really appreciate the help.


Hmm, I've been looking for a decent textbook, and that just might be it. Good suggestion.

It shows funBox as an NSButton pointer, so that looks alright. It also says delegate is a NotSwingSetAppDelegate pointer, but the address is just 0x0. Could that have something to do with it? Am I not getting a proper pointer to the controller?
Yeah, that seems like the issue. Although based on your code I'm not completely sure why.

Adbot
ADBOT LOVES YOU

Doc Block
Apr 15, 2003
Fun Shoe
For whatever reason you're getting nil.

Hell if I can see why, though.

One question: why are you doing
code:
NotSwingSetAppDelegate *delegate = self;
[preferencesWindow setDelegate:delegate];
instead of just
code:
[preferencesWindow setDelegate:self];
?

Also, you can store the delegate as the generic id type, which will allow it to take any object type as a delegate (not that it matters in this instance).
You can check at runtime to see if the delegate responds to the necessary selector by doing
code:
[delegate respondsToSelector:@selector(someSelector:)];
and probably cache the result instead of checking every single time. (do a custom setter that checks for any selectors you need). Probably also define a formal protocol.

Sch
Nov 17, 2005

bla bla blaufos!bla bla blaconspiracies!bla bla bla

Doc Block posted:

The argument is that if some other thread tries to access the ivar after it's been released but before dealloc is finished, having it be nil'ed out will be "safe".

But what if the other thread accesses your ivar after you've released it but *before* you set it to nil? Nilling out ivars will not help you with concurrency!

Having said that, always nil (or reassign) your ivars immediately after releasing them, since you don't want any dangling pointers. Those errors are a bitch to find.

I guess most of this won't be an issue any more in the near future, since ARC should take care of all that silly stuff.

carry on then
Jul 10, 2010

by VideoGames

(and can't post for 10 years!)

NoDamage posted:

Yeah, that seems like the issue. Although based on your code I'm not completely sure why.

Inside the showPreferences: method, it is getting a valid pointer to the App Delegate, it's just not passing it along or storing it correctly in PreferencesController. The ivar is given a property of assign which I think is the one to use, but could be the problem.

Doc Bloc posted:

One question: why are you doing
<thing>
instead of just
<shorter thing>
?

This is another thing that's throwing me: self. The official documentation says it "returns the receiver," but that seems to be in the context of the method -(id)self. If self (the token) works like this in Java, how does preferencesWindow showWindow:self, which instructs preferencesWindow to show its own window, work? I don't understand what, exactly, is passed in when self is given as an argument.

Carthag Tuek
Oct 15, 2005

Tider skal komme,
tider skal henrulle,
slægt skal følge slægters gang



carry on then posted:

Inside the showPreferences: method, it is getting a valid pointer to the App Delegate, it's just not passing it along or storing it correctly in PreferencesController. The ivar is given a property of assign which I think is the one to use, but could be the problem.


This is another thing that's throwing me: self. The official documentation says it "returns the receiver," but that seems to be in the context of the method -(id)self. If self (the token) works like this in Java, how does preferencesWindow showWindow:self, which instructs preferencesWindow to show its own window, work? I don't understand what, exactly, is passed in when self is given as an argument.

Think of it as self being a pointer to the object asking, like "this" in Java.

code:
- (IBAction)showPreferences:(id)sender {
    preferencesWindow = [[PreferencesController alloc] initWithWindowNibName:@"Preferences"];
    NotSwingSetAppDelegate *delegate = self;
    [preferencesWindow setDelegate:delegate];
    [preferencesWindow showWindow:self]; // in this case self = your NotSwingSetAppDelegate
}
NSWindowController showWindow: is an IBAction, that is, you can bind to it in Interface builder (for instance, make a menu item that says "Preferences...", and bind it to showWindow: on your PreferencesController). In that case, showWindow: will be called with the NSMenuItem as its argument, and if you've overriden showWindow:, you could do some magic here (change the name of the menu or check its tag or whatever). It doesn't make much sense in the context of a preferences window, and since nil is actually allowed and you haven't overriden showWindow: you can just send nil.

Sch
Nov 17, 2005

bla bla blaufos!bla bla blaconspiracies!bla bla bla

carry on then posted:

This is another thing that's throwing me: self. The official documentation says it "returns the receiver," but that seems to be in the context of the method -(id)self. If self (the token) works like this in Java, how does preferencesWindow showWindow:self, which instructs preferencesWindow to show its own window, work? I don't understand what, exactly, is passed in when self is given as an argument.

Think of self as local variable that's available in every Objective-C method and that refers to the object that performs the method. You can do whatever you want with it: message it, pass it as an argument to other methods and functions, even reassign it (like you do in -init methods).

Now what's actually going on is this: every Objective-C method call is actually translated by the compiler into the C function objc_msgSend(id self, SEL cmd, ...) or one of its siblings. As you can see from that definition, self is actually a hidden parameter that's passed along with every method call. (The other hidden parameter, cmd, contains the selector (i.e. the name) of the method.)

carry on then
Jul 10, 2010

by VideoGames

(and can't post for 10 years!)

Thanks for the info on self. I suspected it worked like that, but the snippet I found when trying to open a window used self. That'll teach me to read the documentation.

I removed the property on PreferencesController's delegate and implemented my own setter:
code:
- (void)setDelegate:(NotSwingSetAppDelegate *)dg {
    delegate = dg;
    [funBox setState:[delegate fun]];
}
In order to see if that was the reason I wasn't getting a pointer. Now, when I put a breakpoint on the second line of that method, I can see that I do have a valid memory address for delegate (where I didn't before), but that I no longer have a valid memory address for funBox (where I did before.) What's more, if I set a breakpoint in the closePreferences: method:
code:
- (IBAction)closePreferences:(id)sender {
    NSLog(@"Sending Message.");
    [delegate preferencesDidChange:[funBox state]];
}
I can see that delegate is at 0x0 and funBox has a valid address! Somewhere between opening the dialog and clicking the close button, it manages to lose the NotSwingSetAppDelegate pointer.

More and more, this is starting to sound like one of those bugs that arises from fumbling around in the dark doing everything until it works. I think I'll take a step back and do some more reading while messing around with this some more. Thanks everyone for the extremely helpful responses.

Doc Block
Apr 15, 2003
Fun Shoe

mc.schroeder posted:

But what if the other thread accesses your ivar after you've released it but *before* you set it to nil? Nilling out ivars will not help you with concurrency!

I hope I wasn't giving the impression that I thought it would.

Dangling pointers can be a problem, though.

Toady
Jan 12, 2009

Sir Davey posted:

HOWEVER, I was not wrong to wonder wtf was happening when the object was being deallocated even though the retainCount was far greater than 1!

No, don't look at retainCount at all, because it is useless for debugging memory management issues, and the documentation is explicit about this. An object could be retained by any number of frameworks without you knowing. Some Cocoa classes even return cached instances that never get released (e.g., NSNumbers representing integers between 1 and, I believe, 20). There are specialized tools for debugging memory leaks that you are supposed to use.

newreply.php
Dec 24, 2009

Pillbug
I don't usually post to ask for help, but this has been a mystery to me for 4 days and I just can't wrap my head about what's happening. I probably hosed something up by trying to fix it already but here it goes:

The setup:
I have a Core Data sourced UITableView on my homescreen. Users can add items by clicking a lil' "+" button taking them through two views to enter data. The last view has a save button that saves the item into the managedobjectcontext and pops back to the root view controller. Last view also has a back button leading to the second view so the data there can be changed as well.

The problem:
The problem occurs when a user is not saving the object but pressing back until he's at the homescreen. In this case the tableview will show the unsaved object, and the app will (obviously) crash and burn when trying a delete on it. When I restart the app the object will be gone as it should, even though the crash happens right on saving the context (also wondering why it's not logged because I passed an NSError, but I guess it doesn't work exactly the same as try/catching)

What I've tried so far:
Changing around how the managedobjectcontext and fetchcontroller are instantiated in the root view controller, forcing a delete on back button press with unsaved objects, put [self.tableView reloadData] pretty much everywhere I could stick it, using copy instead of retain, and lots more desperate attempts that have probably hosed my code up beyond salvation.

Some code I guess, you get to point and laugh.

HomeScreenViewController.h (the root view controller)
code:
@interface HomeScreenViewController : UITableViewController<NSFetchedResultsControllerDelegate> {
}
@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;
@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;

- initInManagedObjectContext:(NSManagedObjectContext *)context;

@end
self.managedObjectContext
code:
- (NSManagedObjectContext *)managedObjectContext{
    if (__managedObjectContext == nil) 
    { 
        return [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext]; 
    }
    else return __managedObjectContext;
}
self.fetchedResultsController
code:
- (NSFetchedResultsController *)fetchedResultsController
{
    if (__fetchedResultsController != nil)
    {
        return __fetchedResultsController;
    }
    
    /*
     Set up the fetched results controller.
     */
    // Create the fetch request for the entity.
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Server" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];
    
    // Set the batch size to a suitable number.
    [fetchRequest setFetchBatchSize:20];
    
    // Edit the sort key as appropriate.
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"servertype" ascending:NO];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
    
    [fetchRequest setSortDescriptors:sortDescriptors];
    
    // Edit the section name key path and cache name if appropriate.
    // nil for section name key path means "no sections".
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"servertype" cacheName:nil];
    self.fetchedResultsController = aFetchedResultsController;
    __fetchedResultsController.delegate = self;
    
    [aFetchedResultsController release];
    [fetchRequest release];
    [sortDescriptor release];
    [sortDescriptors release];
    
	NSError *error = nil;
	if (![self.fetchedResultsController performFetch:&error])
    {
	    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
	    abort();
	}
    
    return __fetchedResultsController;
}  
Pushing first "Add" view
code:
- (void)add:(id)sender
{
    Server *server = [NSEntityDescription insertNewObjectForEntityForName:@"Server" inManagedObjectContext:self.managedObjectContext];
    Authenticator *authenticator = [NSEntityDescription insertNewObjectForEntityForName:@"Authenticator" 
inManagedObjectContext:self.managedObjectContext];
    server.authenticator = authenticator;
    PickServerTypeViewController *pstv = [[PickServerTypeViewController alloc]initWithStyle:UITableViewStyleGrouped];
    pstv.server = server;
    [self.navigationController pushViewController:pstv animated:YES];
    [server release];
    [pstv release];
}
First "Add" view pushing second one upon selection
code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
    self.server.servertype = cell.textLabel.text;
    self.server.alias = [NSString stringWithFormat:@"New %@ server",self.server.servertype];
    EditServerViewController *serverview = [[EditServerViewController alloc]initWithStyle:UITableViewStyleGrouped];
    serverview.title = self.server.alias;
    serverview.server = self.server;
    [self.navigationController pushViewController:serverview animated:YES];
    [serverview release];
    self.server = nil;
    [self.server release];
    pickedServer = YES;
}
"Save" method on second view:
code:
- (void)save
{
    NSError *error = nil;
    [self.server.managedObjectContext save:&error];
    if (error != nil){
        UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Error" message:[error localizedDescription] delegate:self cancelButtonTitle:@"OK" 
otherButtonTitles:nil, nil];
        [alert show];
        NSLog(@"Save failed: %@", [error localizedDescription]);
        [alert release];
    }
    else {
        saved = YES;
        [self.navigationController popToRootViewControllerAnimated:YES];
    }
}
Attempt to clean up after myself when leaving view without saving:
(i do realize all the setting to nil is probably useless)
code:
- (void)viewWillDisappear:(BOOL)animated
{
    if (!saved){
        self.server = nil;
    }
    [super viewWillDisappear:animated];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
    [self.navigationController setToolbarHidden:YES];
    [self.server release];
}
BONUS: fetchedresultscontroller delegate method from rootviewcontroller
code:
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
    [self.tableView beginUpdates];
}

- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
           atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
    switch(type)
    {
        case NSFetchedResultsChangeInsert:
            [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] 
withRowAnimation:UITableViewRowAnimationFade];
            break;
            
        case NSFetchedResultsChangeDelete:
            [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] 
withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath
{
    UITableView *tableView = self.tableView;
    
    switch(type)
    {
            
        case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
            
        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 
withRowAnimation:UITableViewRowAnimationFade];
            break;
            
        case NSFetchedResultsChangeUpdate:
            [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            break;
            
        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 
withRowAnimation:UITableViewRowAnimationFade];
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    [self.tableView endUpdates];
}
This does get called as it should when I'm instantiating my object in the first "Add" view, but after that, nothing. Which is correct (if I'm not saving at least), but I don't want that ghost unsaved object in there since it leads to all sort of indexpath trouble when deleting. Also: it's an unsaved object, it's got no business in my saved objects list
:colbert:

I'll be glad to post more code if you need it.

e: also tried resetting and rollback'ing the context on viewwillappear for the root view

newreply.php fucked around with this message at 22:02 on Aug 10, 2011

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

newreply.php posted:

backing out of core data managed object creation

Fundamentally, what you're trying to do (I think) is:

1. Make a new instance of a managed object.
2. Let the user dick around with it.
3. If they hit 'save', keep it. If they back out entirely, lose it.

The idiomatic way to do this is to instantiate a new managed object context, then insert your new managed object into this 'scratchpad' context. If you decide you want to keep the new object (user hits 'save'), merge the changes into your main managed object context. If you choose instead to forget about the new object, just reset the scratchpad context.

There's a section of the Core Data Programming Guide that talks about this kind of thing, and check out the sample code project "CoreDataBooks" for an example of how to do exactly this.

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice
That's definitely the more flexible way of doing it... However why don't you just delete the object if the user doesn't hit save and the object is a new object?

The problem is the insert happens in memory and nothing you are doing deletes that inserted object. I presume the save fails because the new blank object doesn't satisfy some CoreData constraints you have in your model.


If you are trying to use the undo functionality, check out the CoreData guide and follow its directions to the letter or you will have endless trouble.

fankey
Aug 31, 2001

Given a crash log and the .dSYM file associated with the release, what's the easiest way to symbolize the crash log? I'm using a script which uses xcrun to package my app so it's not in the Archived Applications section of Organizer. XCode 3.2.5 in case that matters.

dizzywhip
Dec 23, 2005

So I've made some progress on the issue I posted about earlier. To remind you guys, my problem is basically that I have a layer-backed view whose size changes periodically, and I'm having issues with the layer content getting stretched and distorted as the view's size changes. I've discovered the cause of the issue, but I can't figure out how to properly solve it.

The size of the view is calculated and set in a relatively expensive layout method. Back before I started using layers, I would just call this layout method at the beginning of drawRect right before I started drawing, and everything worked fine.

Now, since I'm using layers, I don't use drawRect anymore and instead use drawLayer:inContext:. It turns out that setting the view size within that method causes the stretching. For example, if the view gets taller in that method, the layer content will be drawn stretched out vertically. This happens even if I set the layer's frame to match the enclosing view's frame.

The good news is that everything works fine if I instead calculate the layout at the same time that I call setNeedsDisplay on the content layer. The bad news is that within a single event loop I might be calling setNeedsDisplay on the layer several times depending on the event, and I have no way of reliably predicting whether any particular call is the last one of the event loop. Since my layout method is somewhat expensive, it's very wasteful to call it multiple times for a single redraw.

So basically I need to somehow hook into the span of time between the final time I call setNeedsDisplay on a particular layer and the subsequent drawLayer method. Anyone have any ideas on how to do that?

tl;dr: Is there any way to get a notification or callback or whatever when the event loop is finished, but before things are redrawn?

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice
Can't you just call setNeedsLayout? I would think that it just caches that and waits until the end of the loop to actually do the layout, but I'd have to test that to be 100% certain... It might happen immediately.

You can schedule something to happen at the start of the next run loop iteration by using [[NSRunLoop currentRunLoop] performSelector:target:argument:order:modes], if a slight delay is acceptable.

dizzywhip
Dec 23, 2005

Actually, yes, that seems to work great! I had looked at setNeedsLayout, but I think I misinterpreted how it worked and I didn't think it was gonna work for me. Thank you for the suggestion, this problem has been bugging the crap out of me for a very long time!

newreply.php
Dec 24, 2009

Pillbug

pokeyman posted:

Fundamentally, what you're trying to do (I think) is:

1. Make a new instance of a managed object.
2. Let the user dick around with it.
3. If they hit 'save', keep it. If they back out entirely, lose it.

The idiomatic way to do this is to instantiate a new managed object context, then insert your new managed object into this 'scratchpad' context. If you decide you want to keep the new object (user hits 'save'), merge the changes into your main managed object context. If you choose instead to forget about the new object, just reset the scratchpad context.

There's a section of the Core Data Programming Guide that talks about this kind of thing, and check out the sample code project "CoreDataBooks" for an example of how to do exactly this.
Exactly! This seems to do pretty much what I was looking for, I'd never have figured this out by myself. It seems terribly convoluted when compared to Java/.NET ORM's though, first time I've encountered something that doesn't seem intuitive at all in CocoaTouch.

Thanks a bunch, pretty sure I'll get this working now. Would have been finished already if I did everything with NSUserPreferences but that wasn't an option due to sensitive information being stored, even if it is pretty simple data-graph-wise.

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

newreply.php posted:

It seems terribly convoluted when compared to Java/.NET ORM's though, first time I've encountered something that doesn't seem intuitive at all in CocoaTouch.

For what it's worth, Ender.uNF's suggestion of just deleting the object should work too. My (thankfully limited) experience with NSFetchedResultsController has led me to believe that you're best off letting the managed object context and fetched results controller figure poo poo out themselves and to stay out of their way. (And this is why I've stopped using NSFetchedResultsController.)

Mighty Zoltar
Aug 18, 2004

I AM A PIECE OF SHIT. IF YOU SEE ME ON THE STREET, PLEASE STAB ME.
Hopefully i have an easy question. Not being a developer yet, i dont appear to be able to find an answer to my question anywhere else thus far.

Is it possible to use a web link to open an app on the iphone/ipad. That is, either go to a website to open the app, and better yet, create a shortcut to it. If thstbis possible, can it be taken a step further and open an app in a specific state? For example, you click on an app link and the store opens on the right page. I'd like a certain file/whatever to open in an app.

Short version - can i create hyperlinks that would open something like goodreader with a specific document opened within it?

Thanks in advance.

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

Mighty Zoltar posted:

Hopefully i have an easy question. Not being a developer yet, i dont appear to be able to find an answer to my question anywhere else thus far.

Is it possible to use a web link to open an app on the iphone/ipad. That is, either go to a website to open the app, and better yet, create a shortcut to it. If thstbis possible, can it be taken a step further and open an app in a specific state? For example, you click on an app link and the store opens on the right page. I'd like a certain file/whatever to open in an app.

Short version - can i create hyperlinks that would open something like goodreader with a specific document opened within it?

Thanks in advance.

Yes, you can have your app launched with a custom url scheme (something like someApp://blah) and you can parse that URL to obtain information / do different things on launch based on it.

Google 'iphone sdk custom url scheme' for lots and lots of info / examples, etc.

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

Mighty Zoltar posted:

Short version - can i create hyperlinks that would open something like goodreader with a specific document opened within it?

What Lumpy said, though if you're trying to link to someone else's app, you're at their mercy. If they ever change their URL scheme, your links stop working. If you're talking about an app you control, then obviously you can handle that.

Mighty Zoltar
Aug 18, 2004

I AM A PIECE OF SHIT. IF YOU SEE ME ON THE STREET, PLEASE STAB ME.
Thats pretty much wha i wanted to hear, and it would be for my own app.

Final question on this i think - could i have an app create a html link which looks how i want (small webpage image for example), which the app then saves to the app main ipad/iphone app screen, then open the right area of the app on open?

Again using the goodreader example, i make a doc, ask for it to save as a quick link, where it drops a html link icon on the homescreen, shows a preview pic of the doc, and open the doc on a press?

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

Mighty Zoltar posted:

Thats pretty much wha i wanted to hear, and it would be for my own app.

Final question on this i think - could i have an app create a html link which looks how i want (small webpage image for example), which the app then saves to the app main ipad/iphone app screen, then open the right area of the app on open?

Again using the goodreader example, i make a doc, ask for it to save as a quick link, where it drops a html link icon on the homescreen, shows a preview pic of the doc, and open the doc on a press?

You'll need to do this through Safari, instructing the user to save a link to the home screen. You can set its icon there through a <link> tag.

Unless you don't plan on distributing your app through the app store, in which case you can check out the UIWebClip class and the web clip methods on UIApplication.

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.
I can't figure this thing out about a table view cell's editing accessory view. I've made a little project to show off the issue I'm having. If you have a minute, could you run it in the simulator for me? Selecting a cell toggles its editing state if you want to play with it.

In words, the problem I'm having is some weird animation in a UITableViewCell's editingAccessoryView on the first time the cell enters editing mode. I've found a workaround but I'd like to understand what's going on.

If you run the app in the project, you'll see a table view. Edit it. Each cell has a round rect push button for an editingAccessoryView, which should slide in when entering edit mode. Watch the animation closely! The first time you hit the edit button, the rows without the workaround have the button's title slide in from the top, while the rows with the workaround slide in as expected. And it's only the first time entering edit mode; each subsequent time, you see the normal animation.

Can anyone see why this is happening?

OHIO
Aug 15, 2005

touchin' algebra

pokeyman posted:

I can't figure this thing out about a table view cell's editing accessory view. I've made a little project to show off the issue I'm having. If you have a minute, could you run it in the simulator for me? Selecting a cell toggles its editing state if you want to play with it.

In words, the problem I'm having is some weird animation in a UITableViewCell's editingAccessoryView on the first time the cell enters editing mode. I've found a workaround but I'd like to understand what's going on.

If you run the app in the project, you'll see a table view. Edit it. Each cell has a round rect push button for an editingAccessoryView, which should slide in when entering edit mode. Watch the animation closely! The first time you hit the edit button, the rows without the workaround have the button's title slide in from the top, while the rows with the workaround slide in as expected. And it's only the first time entering edit mode; each subsequent time, you see the normal animation.

Can anyone see why this is happening?

That's weird. I messed around with your sample code, and although I couldn't come up with why, I can reproduce the effect with this code. (just used in a View template project)

code:
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(150, 100, 62, 32);
[button setTitle:@"Supden" forState:UIControlStateNormal];

CGRect og_frame = button.titleLabel.frame;

button.titleLabel.frame = CGRectZero;

[self.view addSubview:button];

[UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationCurveEaseIn animations:^(void){
    button.frame = CGRectOffset(button.frame, -50, 0);
    button.titleLabel.frame = og_frame;
} completion:^(BOOL finished) {

}];
So in your sample code I can revert your fix by going like:
code:
- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    for (NSUInteger i = 0; i < 6; i++) {
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
        UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
        
        [cell setEditing:YES animated:NO];
        [cell setEditing:NO animated:NO];
        
        if(i % 2 == 0) {
            UIButton *button = (UIButton*)cell.editingAccessoryView;
            button.titleLabel.frame = CGRectZero;
        }
    }
}
I don't know if that's helpful. Something about the button title's frame not being created at first?

lord funk
Feb 16, 2004

I cannot find any documentation about this behavior. I've added a UINavigationBar over a keyboard input, with two buttons that act as 'Tab' buttons to get to other textfields.

The problem is: the keyboard autocorrects touches away from the buttons. If you type a number, then (relatively) quickly press the kNext button, it will press Delete instead. And there's another button (kPrev) that simply won't respond until a second or two pause has happened after pressing a key.



HELP. I don't want to throw out this feature from the app, but as it stands it's unusable.

Edit: at one point, I put HUGE buttons quite some distance from the keyboard. It still acted the same way.

lord funk fucked around with this message at 01:24 on Aug 17, 2011

PT6A
Jan 5, 2006

Public school teachers are callous dictators who won't lift a finger to stop children from peeing in my plane
Perhaps I suffer from mental retardation, because this should be a dead simple thing, but...

How do you (or is there a way to) switch from a debug/development version of an app to the app store version without losing all the data in the app (by removing it outright)? I've been using one of my apps, and I don't want to have to deal with the expiring development provisioning certificates, but I don't want to lose my stored data either. I sent myself a coupon, so I do have the App Store version in iTunes. I figured it would overwrite the development version, but I suppose this was a silly thing to think since that would be a very, very annoying behaviour in many circumstances.

Perhaps I'm not googling the right thing, but I can't find an answer.

EDIT: I was fairly frightened that I had found a major bug that no one had reported, but no, it was just a lack of a provisioning profile. I suppose I feel slightly better now, but this is still an annoying problem.

EDIT 2: I seem to have solved it by dragging the app from the Apps section to my iPhone in iTunes and re-syncing. Probably should have tried that first before freaking out...

PT6A fucked around with this message at 03:43 on Aug 17, 2011

Sewer Adventure
Aug 25, 2004

lord funk posted:

I cannot find any documentation about this behavior. I've added a UINavigationBar over a keyboard input, with two buttons that act as 'Tab' buttons to get to other textfields.

The problem is: the keyboard autocorrects touches away from the buttons. If you type a number, then (relatively) quickly press the kNext button, it will press Delete instead. And there's another button (kPrev) that simply won't respond until a second or two pause has happened after pressing a key.



HELP. I don't want to throw out this feature from the app, but as it stands it's unusable.

Edit: at one point, I put HUGE buttons quite some distance from the keyboard. It still acted the same way.

Probably won't fix it but you should use a UIToolbar for this and not a UINavigationBar

stray
Jun 28, 2005

"It's a jet pack, Michael. What could possibly go wrong?"
Why is it so hard to find some decent sample code that shows you how to build an app in Xcode 4 that uses a UITabBarController at its root, where one of the tabs gives you a UINavigationController that lets you drill down from a UITableView to a UIView?

I mean, that's got to be one of the most common development scenarios, right? All I could find were a couple of videos, but one is from Xcode 3 and the other shows the guy dragging a nav controller into the tab bar's nib, then pointing it at a totally empty view. For example, when the nav controller is the root view, I know how to change the tab bar's color, but how would I change the color of the nav controller in that example? It kind of cuts off right before the most crucial step.

SmirkingJack
Nov 27, 2002
Ok, I'm going nuts here. My goal is to programmatically create a DMG file, and my code looks like this:

code:
NSTask *task = [[NSTask alloc] init];
NSString *command = @"/usr/bin/hdiutil";

NSArray *arguments = [NSArray arrayWithObjects:@"create", 
                                               @"-fs", 
                                               @"HFS+", 
                                               @"-volname", 
                                               @"'foo'", 
                                               @"-srcfolder", 
                                               @"'/tmp/foo'", 
                                               @"'/tmp/foo.dmg'", nil];

[task setLaunchPath: command];
[task setArguments:arguments];
[task launch];
When I run it, I get this error:

code:
hdiutil: create failed - No such file or directory
But if I punch it into Terminal it works fine. /tmp/foo exists, is readable and is a directory with contents, I can't think of what it could be complaining about. Any ideas?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
Quotation marks are interpreted by the shell, not the kernel. You don't need them if you're splitting your command line up into separate arguments yourself.

SmirkingJack
Nov 27, 2002

rjmccall posted:

Quotation marks are interpreted by the shell, not the kernel. You don't need them if you're splitting your command line up into separate arguments yourself.

Dagnabbit. I swear, I SWEAR, I tried that. Ah well, thanks, that did it.

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

stray posted:

Why is it so hard to find some decent sample code that shows you how to build an app in Xcode 4 that uses a UITabBarController at its root, where one of the tabs gives you a UINavigationController that lets you drill down from a UITableView to a UIView?

I mean, that's got to be one of the most common development scenarios, right? All I could find were a couple of videos, but one is from Xcode 3 and the other shows the guy dragging a nav controller into the tab bar's nib, then pointing it at a totally empty view. For example, when the nav controller is the root view, I know how to change the tab bar's color, but how would I change the color of the nav controller in that example? It kind of cuts off right before the most crucial step.

I just did this on Monday. I am on my phone right now, but I will make a sample project and a quick step by step when I get home in 8 hours or so. I had some trouble at first, but I was making it far too hard, it turned out to be one of those "oh, duh!" things.

Akuma
Sep 11, 2001


Oh my god this is driving me crazy. I'm not new to iOS development, or even submitting apps, but I can't for the life of me get the Application Loader to accept my app!

It says:

Application failed codesign verification. The signature was invalid or it was not signed with an Apple submission certificate.

But it was! I've selected the correct iPhone Distribution profile in the Code Signing Identity section of both my target and my project. I'm using a valid App Store distribution profile and submission certificate. The bundle identifier matches the profile (obviously, or I wouldn't be able to select it...)

I don't know what the gently caress! I can sign development and adhoc distribution builds percectly fine, but no matter what I do the loader won't accept the App Store build.

Are there any obscure things to look out for? Maybe some build settings? I've submitted tons of apps and if this has ever cropped up before it's been human error with selecting the wrong profiles and stuff.

PT6A
Jan 5, 2006

Public school teachers are callous dictators who won't lift a finger to stop children from peeing in my plane

stray posted:

Why is it so hard to find some decent sample code that shows you how to build an app in Xcode 4 that uses a UITabBarController at its root, where one of the tabs gives you a UINavigationController that lets you drill down from a UITableView to a UIView?

I mean, that's got to be one of the most common development scenarios, right? All I could find were a couple of videos, but one is from Xcode 3 and the other shows the guy dragging a nav controller into the tab bar's nib, then pointing it at a totally empty view. For example, when the nav controller is the root view, I know how to change the tab bar's color, but how would I change the color of the nav controller in that example? It kind of cuts off right before the most crucial step.

Are you using Interface Builder for the interface or creating it programatically?

In IB, if I've understood what you want correctly, you would do the following:

First, switch the view mode to "As List". It will make everything much easier.

In MainWindow.xib, select the Tab Bar Controller and open the attributes inspector. At the top, it should have a list of the tabs in the tab bar, followed by "View Controller" by default. Click on View Controller and a drop-down menu will open. Switch that to Navigation Controller instead.

Now, find the navigation controller in the NIB hierarchy. Underneath the navigation controller there should be a view controller. This is your initial view controller. Use the inspector to switch its class identity to the desired viewcontroller class for the first view in that navigation hierarchy, and to switch it's NIB to the desired NIB.

From here on, you can use that root view as you would the root view of any NavigationController, tab bar or not.

OHIO
Aug 15, 2005

touchin' algebra

Akuma posted:

Application failed codesign verification. The signature was invalid or it was not signed with an Apple submission certificate.

The last thing I check if this fails is my scheme. Are you 'Archiving' it? Edit your scheme and see what the build configuration is under the 'Archive' section on the left.

Akuma
Sep 11, 2001


Nope! Still don't know what's up but I remembered the last time I had to submit I ended up using another machine.

Turns out it is signing it properly, because the other machine will submit it trough the application loader just fine. Mine just doesn't work for some reason.

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

OHIO posted:

I don't know if that's helpful. Something about the button title's frame not being created at first?

Good catch. I think what's happening is the UIButton's titleLabel's frame isn't set until it's accessed, or until the button appears on screen. The title label is set as a subview of the button as soon as it's created, but its frame starts at zero.

In other words,
code:
UIButton *button = [UIButton buttonWithStyle:whatever];
[button titleLabel];
makes a button that doesn't have its label animating in weirdly.

I just assumed that whatever initialization that goes on here would occur on the first invocation of -setTitle:forState:. Thinking about it more, maybe it's done this way so the label can be given a size that fits the longest title set for the button? (Though isn't that what -sizeToFit is supposed to accomplish?)

Anyway, I'm much happier with this getter workaround, so thanks for having a look.

Sinestro
Oct 31, 2010

The perfect day needs the perfect set of wheels.
Why is my loving UITableView being retarded and not displaying the data? I have implemented UITableViewDataSource on my controller, so what the gently caress?

ForumListViewController.m
ForumListViewController.h

Adbot
ADBOT LOVES YOU

Zhentar
Sep 28, 2003

Brilliant Master Genius
Probably because you haven't told your UITableView to use your controller as a data source.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply