Question

My goal is to display a UIPopover for each of my UITabBarbuttons when the app for launches as part of my tutorial... I'm doing the following:

How do I extract the frame from UIView *tabView = [[appDelegate tabBarMutableArray] objectAtIndex:1]; Which is the first UITabBarButton.

Array AppDelegate: <UITabBarButton: 0x145d06a70; frame = (254 1; 76 55); opaque = NO; layer = <CALayer: 0x17802c160>>

Right now I'm manually entering the GCRect of 254,712,76,55. I get 712 by subtracting 768 - 56, and the popover is in the perfect position. But I'd rather do the calculations by retreving the values... So how do I extract the frame = (254 1; 76 55) part of the results above?

frame = CGRectMake(254,712,76,55);

AppDelegate.h

#import <UIKit/UIKit.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

- (NSMutableArray *)tabBarMutableArray;

@end

AppDelegate.m

#import "AppDelegate.h"

@implementation AppDelegate
#define debug 1

- (NSMutableArray *)tabBarMutableArray;
{
    if (debug==1) {
        NSLog(@"Running %@ '%@'", self.class, NSStringFromSelector(_cmd));
    }

    UITabBarController *tabController           = (UITabBarController *)self.window.rootViewController;
    NSMutableArray     *tabBarItemsMutableArray = [NSMutableArray new];

    UITabBar *tabBar = tabController.tabBar;

    for (UIView *view in tabBar.subviews)
    {
        [tabBarItemsMutableArray addObject:view.description];
    }

    return  tabBarItemsMutableArray;
}

viewcontroller.m

-(void)showHomeTabBarPopOver
{
    if (debug==1) {
        NSLog(@"Running %@ '%@'", self.class, NSStringFromSelector(_cmd));
    }

    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    CGRect frame    = CGRectZero;

    NSLog(@"%@", [appDelegate tabBarMutableArray]);

    NSLog(@"Array AppDelegate: %@", [[appDelegate tabBarMutableArray] objectAtIndex:1]);


    UIView *tabView = [[appDelegate tabBarMutableArray] objectAtIndex:1];
    NSLog(@"tabView %@", [tabView valueForKey:@"frame"]);

    //    frame           = tabView.frame;
    NSLog(@"frame %@", CGRectCreateDictionaryRepresentation(self.view.frame));

    frame = CGRectMake(254,712,76,55); //254,712,76,55

    [_getStartedPopover presentPopoverFromRect:frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

}

Results

2014-02-07 14:35:47.940 mCC HD[1964:60b] (
    "<_UITabBarBackgroundView: 0x145d0cb30; frame = (0 0; 1024 56); autoresize = W; userInteractionEnabled = NO; layer = <CALayer: 0x17802db00>>",
    "<UITabBarButton: 0x145d06a70; frame = (254 1; 76 55); opaque = NO; layer = <CALayer: 0x17802c160>>",
    "<UITabBarButton: 0x145e2e360; frame = (364 1; 76 55); opaque = NO; layer = <CALayer: 0x17003c2e0>>",
    "<UITabBarButton: 0x145d0a060; frame = (474 1; 76 55); opaque = NO; layer = <CALayer: 0x17802c6a0>>",
    "<UITabBarButton: 0x145d0a640; frame = (584 1; 76 55); opaque = NO; layer = <CALayer: 0x17802ca20>>",
    "<UITabBarButton: 0x145d0ae60; frame = (694 1; 76 55); opaque = NO; layer = <CALayer: 0x17802cda0>>",
    "<UIImageView: 0x145d0edd0; frame = (0 -0.5; 1024 0.5); autoresize = W; userInteractionEnabled = NO; layer = <CALayer: 0x17802f0a0>>"
)
2014-02-07 14:35:47.940 mCC HD[1964:60b] Running AppDelegate 'tabBarMutableArray'
2014-02-07 14:35:47.941 mCC HD[1964:60b] Array AppDelegate: <UITabBarButton: 0x145d06a70; frame = (254 1; 76 55); opaque = NO; layer = <CALayer: 0x17802c160>>
2014-02-07 14:35:47.943 mCC HD[1964:60b] frame {
    Height = 768;
    Width = 1024;
    X = 0;
    Y = 0;

Thanks in advance...

-PaulS

Was it helpful?

Solution

EDIT:

(Sorry, in my first answer I did not look at how the tabBarMutableArray is created.)


In your AppDelegate the tabBarItemsMutableArray (which is the return value of your -tabBarMutableArray method) is created like this:

for (UIView *view in tabBar.subviews)
{
    [tabBarItemsMutableArray addObject:view.description];
}

Hence there are no UIView objects contained in that array but NSString objects (the descriptions of all the subviews). That is why the following line in your viewcontroller.m is incorrect and won't work as desired:

    UIView *tabView = [[appDelegate tabBarMutableArray] objectAtIndex:1];

The right hand side of that line is a NSString, the left hand side is a UIView.


You can fix this problem adding the lines

AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];        
UITabBarController *tabController = (UITabBarController *)appDelegate.window.rootViewController;
UITabBar *tabBar = tabController.tabBar;
UIView *tabView = [tabBar.subviews objectAtIndex:1];
CGRect frame = tabView.frame

to your -showHomeTabBarPopOver method. (Though there are neater methods depending on what you want to do...)


If you need the frames for all tab bar items and not only this particular one "at index: 1" I suggest you create a property in your AppDelegate.h:

@property (strong, nonatomic) NSArray *tabBarViews;

and implement its getter method in your AppDelegate.m:

- (NSArray *)tabBarViews {
    UITabBarController *tabController  = (UITabBarController *)self.window.rootViewController;
    UITabBar *tabBar = tabController.tabBar;

    return tabBar.subviews;
}

Then you can access your tab bar views more easily from within your viewcontroller.m including their frames:

AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; 

UIView *tabView0 = [appDelegate.tabBarViews objectAtIndex:0];
CGRect frame0 = tabView0.frame;

UIView *tabView1 = [appDelegate.tabBarViews objectAtIndex:1];
CGRect frame1 = tabView1.frame;

etc.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top