Limit UIAlertView TextField delegate.

Discussion in 'iOS Programming' started by IDMah, Nov 4, 2013.

  1. IDMah macrumors 6502

    IDMah

    Joined:
    May 13, 2011
    #1
    Hi all I got this to work but confused by other examples and if I am doing it correctly..

    Code:
    -(void)showWinAlert
    {
        NSLog(@"gameTime was:%@",userScore.gameTime);
        
        NSMutableString *messageAlert = [[NSMutableString alloc]initWithFormat:
                                         @"with Time: %@",userScore.gameTime];
        // Testing alert //
        winAlert = [[UIAlertView alloc] initWithTitle:@"New High Score!!!" 
                                              message:messageAlert
                                             delegate:self
                                    cancelButtonTitle:@"OK !"
                                    otherButtonTitles:nil];
        
        // if High Score then //
        [winAlert setAlertViewStyle:UIAlertViewStylePlainTextInput];
        [winAlert textFieldAtIndex:0].keyboardAppearance = UIKeyboardAppearanceAlert;
        [winAlert  becomeFirstResponder];    
        [[winAlert textFieldAtIndex:0] setTextAlignment:UITextAlignmentCenter];
        [winAlert textFieldAtIndex:0].text=@"YourName";
        
        // hilight all the text in the field //
       
        // delegate the textfield in the Alert so we can limit size of input //
        UITextField *theTitleTextField = [winAlert textFieldAtIndex:0];
    // **this is the confusing line. makes sense to me but.. 
        theTitleTextField.delegate = [winAlert delegate];
    
    // ** most examples I found say this but this gives me an warning. 
    // warning: Semantic Issue: Assigning to 'id<UITextFieldDelegate>' from incompatible type 'HighScoreViewControl'
    
        theTitleTextField.delegate = self; 
    
        [myTable reloadData];
        [winAlert show];
            
    }
    // then I do this //
    // Limit textfield to MAXTEXT // 
    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 
    {
        if ([textField.text length] >= MAXLENGTH) {
            textField.text = [textField.text substringToIndex:MAXLENGTH-1];
            NSLog(@"calling Limit input");
            return NO;
        }
        return YES;
    }
    
    
    Like I said above works just wondering about the discrepancy between examples I found on web and what I need to do. Is it because the UIAlert is controller for the view and therefore I need to pass the textfield up through it, to self. Is there a better way to do this. will I run into any error later on doing it this way?

    thanks
    Ian
     
  2. Sonnestah macrumors regular

    Joined:
    Mar 2, 2013
    #2
    That makes indeed no sense, what it is doing is setting its delegate to self in a fancy weird way.

    Just keep

    Code:
    theTitleTextField.delegate = self;
    And that's it
     
  3. devilofspades, Nov 4, 2013
    Last edited: Nov 4, 2013

    devilofspades macrumors member

    Joined:
    Jul 20, 2011
    #3

    this is your problem right here

    Code:
        // delegate the textfield in the Alert so we can limit size of input //
        UITextField *theTitleTextField = [winAlert textFieldAtIndex:0];
    // **this is the confusing line. makes sense to me but.. 
    [B][U]theTitleTextField.delegate = [winAlert delegate];[/U][/B]
    // ** most examples I found say this but this gives me an warning. 
    // warning: Semantic Issue: Assigning to 'id<UITextFieldDelegate>' from incompatible type 'HighScoreViewControl'
    
        [B]theTitleTextField.delegate = self; [/B]
    
        [myTable reloadData];
        [winAlert show];
    
    the line "theTitleTextField.delegate = [winAlert delegate];" is already setting the delegate to the winAlert's delegate, which is already "self". so there is no need for this line here "theTitleTextField.delegate = self;", so just remove it and that will fix your problem. also "delegate" is a property not a method (even though a hidden getter "-(id)delegate" method exists, which is why it works) it really should be "winAlert.delegate" not "[winAlert delegate]". it just makes for more "correct" code syntax.

    "dot.syntax" is for properties.
    "[square brackets]" are for methods.
     
  4. IDMah thread starter macrumors 6502

    IDMah

    Joined:
    May 13, 2011
    #4
    Thanks for that clarification.. and note on syntax appreciated..
    changed to:
    Code:
    UITextField *theTitleTextField = [winAlert textFieldAtIndex:0];
        theTitleTextField.delegate = winAlert.delegate;
    
    I was just mentioning the:
    Code:
    theTitleTextField.delegate = self; 
    
    Line because it was what a few search result suggested, but not in my code.

    thanks all
    Ian
     
  5. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #5

    The dot syntax is entirely optional. I know plenty of developers who hate it and never use it under any circumstances.



    Code:
    winAlert.delegate
    and
    Code:
    [winAlert delegate]
    are both valid, and are interchangeable. The one thing that is not interchangeable about the two syntaxes is the handling of pointers of type "id" (anonymous object pointer type). The compiler allows you to send any message (method call syntax) to an id pointer without warning, but it will flag an error if you try to use the dot syntax if winAlert is type id.

    The argument against do syntax is that it is syntactically ambiguous, and makes somebody else's code harder to understand.

    If you see

    someVariable.someField,

    You can't tell from that expression if someVariable is an object, and someField is a property, or if someVariable is a C struct, and someField is a field in the structure. You have to go look up the definition of someVariable to tell which is the case.

    Personally I like the dot syntax for properties and use it, but I dispute your "more correct" statement.
     
  6. devilofspades, Nov 5, 2013
    Last edited: Nov 5, 2013

    devilofspades macrumors member

    Joined:
    Jul 20, 2011
    #6
    i would have to disagree. the only reason "it works" is because properties have a synthesized accessor getter method with the same name as the property. this is the same reason (in reverse) why "myArray.count" works, even though it should be "[myArray count]. "count" is a method and not a property of NSArray and should be treated as such. it just makes for better code consistency. to follow your stand point i could also start method names with capital letters, make class names starting with lowercase letters, etc. its all perfectly legal to do all these things, but it's just poor programming etiquette. that is the reason dot syntax exists in obj-c in the first place. as far as your comment about "id", the compiler allows you to do that because it has no idea what it is sending a message to because of the "blindness" of the process. the fact the compiler throws an warning is a good thing, and means you need to look at what it is you are doing and see if you can do it a different or "better" way. but just wrapping it in some "[ ]" to avoid an error is bad programming. but in this case "winAlert" is not of type "id", it's "delegate" is, and is a property which is why dot syntax works (as that's what it was designed for) and the code compiles just fine with no errors using "winAlert.delegate". i mean we both know in reality they are all "[messages calls]" under the hood, but for the sake of readability it is broke out like the way it is for a reason. my point on your "syntactically ambiguous" comment, would be it wouldn't and shouldn't make much difference either way. all things considered an object and it's properties are very similar to a struct (and probably is a struct under the hood) and can behave in similar ways. this is why dot syntax is used and the more reason to use it in such a way.
     
  7. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #7

    You are welcomed to your opinion. In fact, I use the same style that you do.

    However, you are stating it as a firm coding guideline. It's not. The example of the use of upper and lower case in variable names and method names IS a well established coding convention in Cocoa/Cocoa Touch.

    To quote the official Objective C 2.0 PDF (From Apple's website - can't find the link to it at the moment:)

    And from this article which I did just find on Apple's site:


    That "purely a convenient wrapper" bit sure doesn't sound like a coding rule.
     
  8. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #8
    Some of the following relies on guesswork, because you haven't posted the @interface for the class that contains the showWinAlert method.


    First, consider this code:
    Code:
    theTitleTextField.delegate = self; 
    
    A possible reason it doesn't produce a warning is that the class containing the method is declared as implementing the UITextFieldDelegate protocol.

    If you look at UITextField's delegate property you see this:
    Code:
    @property(nonatomic, assign) id<UITextFieldDelegate> delegate
    
    This means the delegate can be any object type that implements the UITextFieldDelegate protocol. So if the class with the showWinAlert method implements that protocol, then the type of self in the assignment is a suitable type for the delegate.


    Next, consider this code:
    Code:
        theTitleTextField.delegate = winAlert.delegate;
    
    The winAlert.delegate expression has whatever type is declared for the UIAlertView's delegate property.

    Referring to the UIAlertView class reference, we see:
    Code:
    @property(nonatomic, assign) id delegate
    
    with the note to "See UIAlertViewDelegate Protocol Reference for the methods this delegate should implement." So the delegate is declared as being a simple id type, but it's expected to implement methods from the UIAlertViewDelegate protocol.

    When the delegate type is id, this isn't the same as id<UITextFieldDelegate>. You're assigning a less restrictive type (id) to a property that expects a more restrictive type (id<UITextFieldDelegate>), so the compiler warns you about this.

    If the delegate type were id<UIAlertViewDelegate>, then you're still not assigning the expected type, which is id<UITextFieldDelegate>, so you'd still get a warning.

    Whenever you see a compiler warning like this, start by asking yourself "What are the types involved?". You may have to dig into class references to find out exactly what types are expected, and what types are being returned. You'll also have to consider the type of self, i.e. what class the method is being defined in, what its superclass is, what protocols it implements, etc.


    I won't venture a guess as to why the compiler warning mentioned 'HighScoreViewControl' without knowing what class the method is defined in.


    (In the above, I've used the online class references to find the types used by each class's delegate property. Those docs may not be perfectly accurate or in sync with the headers in the SDK. Since the compiler reads headers, refer to those headers for the most accurate info on expected types.)
     

Share This Page