Getting the frame of a particular tab bar item

前端 未结 12 1019
礼貌的吻别
礼貌的吻别 2021-02-02 07:42

Is there a way to find the frame of a particular UITabBarItem in a UITabBar?

Specifically, I want to create an animation of an image \"falling\

相关标签:
12条回答
  • 2021-02-02 07:45

    Swift + iOS 11

    private func frameForTabAtIndex(index: Int) -> CGRect {
        guard let tabBarSubviews = tabBarController?.tabBar.subviews else {
            return CGRect.zero
        }
        var allItems = [UIView]()
        for tabBarItem in tabBarSubviews {
            if tabBarItem.isKind(of: NSClassFromString("UITabBarButton")!) {
                allItems.append(tabBarItem)
            }
        }
        let item = allItems[index]
        return item.superview!.convert(item.frame, to: view)
    }
    
    0 讨论(0)
  • 2021-02-02 07:45

    When initializing a tab bar, give it a tag:

    let tabItem = UITabBarItem(title: "my title", image: nil, tag: 1000)

    Then you can fetch the tab bar using:

    let myTabItem = tabBarController?.tabBar.viewWithTag(1000)

    0 讨论(0)
  • 2021-02-02 07:53

    Tab bar buttons are the only sub views that have user interaction enabled. Check for this instead of UITabBarButton to avoid violating hidden API's.

    for (UIView* view in self.tabBar.subviews)
        {
            if( [view isUserInteractionEnabled] )
            {
                [myMutableArray addObject:view];
            }
    }
    

    Once in the array, sort it based on the origin x, and you will have the tab bar buttons in their true order.

    0 讨论(0)
  • 2021-02-02 07:56

    I'll add what worked for me in my simple UITabBarController scenario, everything is legit but it has an assumption that items are spaced equally. Under iOS7 it returns an instance of an UITabBarButton, but if you'll be using it as UIView* you really don't care what it is and you aren't stating the class explicitly. The frame of the returned view is the frame you're looking for:

    -(UIView*)viewForTabBarItemAtIndex:(NSInteger)index {
    
        CGRect tabBarRect = self.tabBarController.tabBar.frame;
        NSInteger buttonCount = self.tabBarController.tabBar.items.count;
        CGFloat containingWidth = tabBarRect.size.width/buttonCount;
        CGFloat originX = containingWidth * index ;
        CGRect containingRect = CGRectMake( originX, 0, containingWidth, self.tabBarController.tabBar.frame.size.height );
        CGPoint center = CGPointMake( CGRectGetMidX(containingRect), CGRectGetMidY(containingRect));
        return [ self.tabBarController.tabBar hitTest:center withEvent:nil ];
    }
    

    What it does is calculate the rect in the UITabBar where the button resides, finds the center of this rect and digs out the view at that point via hitTest:withEvent.

    0 讨论(0)
  • 2021-02-02 07:56

    redead's answer definitely works so please upvote it.

    I needed to add an activity indicator to the tabBar and to do that I needed the tabBar's rect inside the window so I had to add some additional code to his answer:

    // 1. get the frame for the first tab like in his answer
    guard let firstTab = tabBarController?.tabBar.items?[0].valueForKey("view") as? UIView else { return }
    print("firstTabframe: \(firstTab.frame)")
    
    // 2. get a reference to the window
    guard let window = UIApplication.shared.keyWindow else { return }
    
    // 3. get the firstTab's rect inside the window
    let firstTabRectInWindow = firstTab.convert(firstTab.frame, to: window)
    print("firstTabRectInWindow: \(firstTabRectInWindow)")
    
    0 讨论(0)
  • 2021-02-02 07:57

    By Extending UITabBar

    extension UITabBar {
    
        func getFrameForTabAt(index: Int) -> CGRect? {
            var frames = self.subviews.compactMap { return $0 is UIControl ? $0.frame : nil }
            frames.sort { $0.origin.x < $1.origin.x }
            return frames[safe: index]
        }
    
    }
    
    extension Collection {
    
        subscript (safe index: Index) -> Element? {
            return indices.contains(index) ? self[index] : nil
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题