Set font size for all text views programatically

Discussion in 'iOS Programming' started by moonman239, Feb 11, 2013.

  1. moonman239 macrumors 68000

    Joined:
    Mar 27, 2009
    #1
    Hi guys,

    First of all, I wish to thank you for the tremendous help you have offered me, a novice iOS developer.

    OK, I now have a new problem to solve. My app has a bunch of text views and the font sizes are too small. But there are so many text views that it'd take me forever to set the font size on all of them. So I want to set the size programmatically.

    I have started with this code, which is located in FirstViewController.m, where my text views are:

    Code:
    -(void) viewDidLoad
    UIFont *theTextviewFont = [fontWithName: @"Arial" size:20];
    @end
    
    Now I just need to apply this font to all the text views. Once again, I will appreciate any help I can get!
     
  2. ConCat macrumors 6502a

    ConCat

    Joined:
    Jul 27, 2012
    Location:
    In an ethereal plane of existence.
    #2
    You might want to consider using NSAttributedString. This way you can store the UIFont with the string in one nice tidy object, then display it with "setAttributedText:".
     
  3. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
  4. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #4
    If you are truly lazy you should be able to write a simple method that recursively traverses a view's subviews looking for textViews or if you like any view that responds to setFont: and then sets the font on it.

    You could even have a UIViewController that does this in its viewDidLoad method and then derive all your view controllers from that base class.
     
  5. moonman239 thread starter macrumors 68000

    Joined:
    Mar 27, 2009
    #5
    I tried that. It doesn't work, and from what I read, it's not supposed to.
     
  6. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #6
    What? Why not? :confused:
     
  7. moonman239, Feb 22, 2013
    Last edited: Feb 22, 2013

    moonman239 thread starter macrumors 68000

    Joined:
    Mar 27, 2009
    #7
    I tried what I thought would work, and it didn't. I can't find any Web pages with helpful information on this subject.

    I'll try what you suggested. I do have a question. All the view controllers of concern here are linked to a table view controller, which in turn is linked to a navigation view controller. I can see that the posterity (for lack of a better word) infer the simulated metrics from their parents. Because of this, the view controllers have a functional navigation bar with a functional back button. Does this mean that all the view controllers are automatically derived from the base class of the view controller at the top of the tree? I assume the answer is yes.

    EDIT: I'm going to try every piece of code I have and see what works. When I find that piece of code, I'll be sure to post it here. I now see that I might have been wrong to assume that using the UIAppearance proxy would not work.
     
  8. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #8
    But earlier you said:
    I'm curious where you read that.
     
  9. moonman239 thread starter macrumors 68000

    Joined:
    Mar 27, 2009
    #9
    OK, I think I'm on to something here. Here's the code I tried. It doesn't work.
    EDIT: I should add that I don't see any errors.

    Code:
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didRotate:) name:UIDeviceOrientationDidChangeNotification object:nil];
        UIFont *theTextViewFont = [UIFont fontWithName: @"Arial" size: 50.0f];
        NSAttributedString *textViewText = [[UITextView appearance] attributedText];
        NSMutableAttributedString *modifiedTextViewText = [[NSMutableAttributedString alloc] initWithAttributedString:textViewText];
        [modifiedTextViewText addAttribute:NSFontAttributeName value:theTextViewFont range:NSMakeRange(0, [textViewText length])];
        [[UITextView appearance] setAttributedText:modifiedTextViewText];
    }
    
     
  10. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #10
    Sorry for leading you astray, moonman. After some digging it looks like UITextView doesn't have any UIAppearance customization (i.e. no relevant accessor methods marked with UI_APPEARANCE_SELECTOR) beyond what it inherits from UIScrollView. My apologies.
     
  11. moonman239 thread starter macrumors 68000

    Joined:
    Mar 27, 2009
    #11
    OK, will someone please help me? In FirstViewController.m, this is my new code:

    Code:
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        UIFont *theTextViewFont = [UIFont fontWithName: @"Arial" size: 50.0];
        [self setEveryTextViewFont:self theTVFont:theTextViewFont];
    }
    -(void) setEveryTextViewFont: (UIViewController *)viewController theTVFont:(UIFont *)theFont {
        for (UITextView *textView in [self.view subviews])
        {
            textView.font = theFont;
        }
       for (UIViewController *childVC in viewController.childViewControllers)
       {
           
           [self setEveryTextViewFont:self theTVFont:theFont];
       }
    }
    
    It doesn't work!
     
  12. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #12
    Your recursion looks messed up. You're looping across childVC instances but then calling setEveryTextViewFont: with self and never using childVC.

    P.S. I would probably also add a check to ensure that each subview is a UITextView, just to be safe.
     
  13. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #13
    If I understand what you said I think you believe that having several view controllers in a navigation controller stack relates those view controllers by inheritance. That's not the case.

    I would start out with a method that recursively iterates over a view controller's view looking for text views, and sets their font. Your code kind of does that but it doesn't look at subviews below the view controller's view. It needs to do that.

    Don't try to access another view controller's views in this code.
     
  14. moonman239 thread starter macrumors 68000

    Joined:
    Mar 27, 2009
    #14
    Thank you for pointing that out. It's no wonder the code didn't work. I just changed that line to
    Code:
    [self setEveryTextViewFont:childVC theTVFont:theFont];
    .

    I now understand that the view controllers are not related simply because they're linked by push segues to the first view controller. At first, I didn't understand your second paragraph. I see that what you're saying is each view controller has a view, and those views have subviews. Edit: After taking another look at the code, it now seems like you must be mistaken. The first for loop in setEveryTextViewFont searches for UITextViews in the [self.view subviews] array.

    Like I said, I just fixed the issue dejo mentioned, and I'm going to run the code again. I bet it will work, although I've noticed that sometimes, code that I think should work doesn't.
     
  15. moonman239, Feb 26, 2013
    Last edited: Feb 26, 2013

    moonman239 thread starter macrumors 68000

    Joined:
    Mar 27, 2009
    #15
    OK, this time I think I might have a solution. I dropped the following code in my AppDelegate.m file.

    Code:
    -(void)setFontToEveryTextViewInView:(UIFont *)textViewFont parentView: (UIView *)parentView
    {
        NSLog(@"setFontToEveryTextView");
        NSUInteger *X = 1;
        NSArray *subViews = [parentView subviews];
        NSUInteger *theLength = [subViews count];
        while (X <= theLength)
        {
            if ([[subViews objectAtIndex:X] isKindOfClass:[UITextView class]])
            {
                UITextView *textView = [subViews objectAtIndex:X];
                NSLog(@"Found a text view.");
                textView.font = textViewFont;
            }
            else
            {
                [self setFontToEveryTextViewInView:textViewFont parentView:[subViews objectAtIndex:X]];
            }
        X = X + 1;
        }
    }
    
    -(void)setFontToEveryTextViewInViewController: (UIFont *)textViewFont parentVC: (UIViewController *)parentVC
    {
        NSLog(@"setFontToEveryTextViewInViewController");
        [self setFontToEveryTextViewInView:textViewFont parentView:parentVC.view];
        NSArray *childVCs = parentVC.childViewControllers;
        NSUInteger *X = 1;
        NSUInteger *theLength = [childVCs count];
        while (X <= theLength)
        {
            [self setFontToEveryTextViewInViewController:textViewFont parentView:[childVCs objectAtIndex:X]];
        }
    }
    
    All I need to do is call setFontToEveryTextViewInViewController from applicationDidFinishLaunchingWithOptions, giving it the appropriate arguments. I think this code will do the trick. Cross your fingers!

    EDIT: This code is not working. I got a SIGABRT message. I am considering giving up and just doing the old-fashioned way, however boring it is. Darn you, Xcode, for complicating a conceptually simple task!
     
  16. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State

Share This Page