2012-03-19 10 views
4

私のアプリでは、私はUIPopoverControllerを使用しており、presentPopoverFromRect APIを使用しています。私が今やっていることは、私のUISegmentedControl全体のフレームに設定することです。しかし、私はこれ以上正確でありたいです。 UISegmentedControlで特定のインデックスのフレームを取得する方法はありますか?特定のUISegmentedControlインデックスからフレームを取得しますか?

ありがとうございます!

答えて

4

セグメントが等しい場合は、コントロールの幅を選択したセグメントの数で割ってみましょう(番号が0から始まるため+1)。 EDIT:あなたは、セグメントの中心を取得する必要があるため、この

-(void)showPopover:(id)sender { 
    if ((UISegmentedControl*)sender.selectedSegmentIndex == 0) 
     [self.popover presentPopoverFromRect:CGRectMake(self.segmentedControl.frame.size.width/6, self.segmentedControl.frame.origin.y, aWidth, aHeight)] 
} 

のようにそれは6の上に、(私は3セグメントの実装を仮定している)だ、と3はラインの上に置くでしょう。ここで単純な数学を行うと(全体のコントロールが60ピクセル幅であると仮定します)、次に60/3年齢20となります。各セグメントの幅が20ピクセルであるため、幅が20ピクセルの場合、6を超える幅が正解10になります。

+0

私はあなたが意味することの一例を示すだけでよいので分かりますか? –

+0

編集を確認してください。 – CodaFi

+0

私は2セグメントのUISegmentedControlを持っていて、2番目のセグメントの真ん中を取得しようとしていたので、CGRectMake全体を行い、xの場合はsegmentedControl.frame.size.width/4ですか? –

10

私たちのプロジェクトでは、各セグメントの実際のフレームが必要でしたが、フレーム分割では十分ではありませんでした。ここには、すべてのセグメントの正確なフレームを計算する関数があります。セグメント化されたコントロールの実際のサブビューにアクセスするため、iOSアップデートが破損する可能性があることに注意してください。

- (CGRect)segmentFrameForIndex:(NSInteger)index inSegmentedControl:(UISegmentedControl *)control 
{ 
    // WARNING: This function gets frame from UISegment objects, undocumented subviews of UISegmentedControl. 
    // May break in iOS updates. 

    NSMutableArray *segments = [NSMutableArray arrayWithCapacity:self.numberOfSegments]; 
    for (UIView *view in control.subviews) { 
     if ([NSStringFromClass([view class]) isEqualToString:@"UISegment"]) { 
      [segments addObject:view]; 
     } 
    } 

    NSArray *sorted = [segments sortedArrayUsingComparator:^NSComparisonResult(UIView *a, UIView *b) { 
     if (a.frame.origin.x < b.frame.origin.x) { 
      return NSOrderedAscending; 
     } else if (a.frame.origin.x > b.frame.origin.x) { 
      return NSOrderedDescending; 
     } 
     return NSOrderedSame; 
    }]; 

    return [[sorted objectAtIndex:index] frame]; 
} 
+1

P E R F E C T!ありがとう – SpaceDog

0

これはあなたが何のカスタムを使用していないことを提供することは、誰かがNSSegmentedControlのためのソリューションを探している場合は、私がしましコントロール(スウィフト版)

extension NSSegmentedControl { 

    func frameForSegment(segment: Int) -> NSRect { 
     var left : CGFloat = 0 
     for i in 0..<segmentCount { 
      let w = widthForSegment(i) 
      if i == segment { 
       let off = CGFloat(i) + 2 // Account for separators and border. 
       return NSRect(x: left + off, y: bounds.minY, width: w, height: bounds.height) 
      } 
      left += w 
     } 
     return NSZeroRect 
    } 
} 
0

をセグメント化し、クラス名を照合することなく、より簡単に行うことができます@ erik-aignerの答えを少し修正しました。 UISegmentedControlの場合も同様です。

このバージョンでは、スペーシングと一般的なコードのジオメトリ計算が改善されています。免責条項:ツールバーに配置されたセグメント化されたコントロールに対してのみテストされました。

import AppKit 

public extension NSSegmentedControl { 

    /// The width of a single horizontal border. 
    public static let horizontalBorderWidth: CGFloat = 3 

    /// The height of a single vertical border. 
    public static let verticalBorderWidth: CGFloat = 2 

    /// The horizontal spacing between segments. 
    public static let horizontalSegmentSpacing: CGFloat = 1 

    /// Returns the frame of the specified segment. 
    /// 
    /// - Parameter segment: The index of the segment whose frame should be computed. 
    /// - Returns: The frame of the segment or `.zero` if an invalid segment index is passed in. 
    public func frame(forSegment segment: Int) -> NSRect { 
     let y = bounds.minY - NSSegmentedControl.verticalBorderWidth 
     let height = bounds.height 
     var left = NSSegmentedControl.horizontalBorderWidth 

     for index in 0..<segmentCount { 
      let width = self.width(forSegment: index) 
      if index == segment { 
       return NSRect(x: left, y: y, width: width, height: height) 
      } 
      left += NSSegmentedControl.horizontalSegmentSpacing 
      left += width 
     } 

     return .zero 
    } 

} 
関連する問題