web-dev-qa-db-ja.com

UIRefreshControlのオフセット

私は現在、アプリケーションにJASidePanelを使用しており、そのためのViewControllersの1つとしてUIRefreshControlを備えたUITableViewcontrollerがあります。テーブルビューの幅は320ピクセルの幅のままなので、UIRefreshControlはビューの真ん中の中央に配置されます。サイドパネルを表示したときに中央に表示されるように、UIRefreshControlをオフセットする方法(xを左に20ピクセル移動)があるかどうかを確認しようとしています。

ありがとう! JASidePanel

27
user754905

UIRefreshControlのフレームを設定する必要があります。このコードを使用

UIRefreshControl *refContr=[[UIRefreshControl alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
[refContr setTintColor:[UIColor blueColor]];
[refContr setBackgroundColor:[UIColor greenColor]];

[stocktable addSubview:refContr];
[refContr setAutoresizingMask:(UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleLeftMargin)];

[[refContr.subviews objectAtIndex:0] setFrame:CGRectMake(30, 0, 20, 30)];


NSLog(@"subViews %@",refContr.subviews); 

出力:
Output

33
Warewolf

boundsを編集してみてください。たとえば、コントロールを+ 50px下に移動するには、次のようにします。

refreshControl.bounds = CGRectMake(refreshControl.bounds.Origin.x,
                                   -50,
                                   refreshControl.bounds.size.width,
                                   refreshControl.bounds.size.height);
[refreshControl beginRefreshing];
[refreshControl endRefreshing];
58
user1195202

UIRefreshControlを下に移動するために、これを行う必要がありました。私の解決策は、UIRefreshControlをサブクラス化し、layoutSubviewsメソッドを上書きして、各サブビューにCAAffineTransform変換を設定することでした。残念ながら、UIRefreshControlに変換を設定することはできません。

必要に応じてxOffsetとyOffsetを変更します。

@interface MyUIRefreshControl : UIRefreshControl
@end

@implementation MyUIRefreshControl

- (void)layoutSubviews {
    [super layoutSubviews];
    for (UIView *view in self.subviews) {
        view.transform = CGAffineTransformMakeTranslation(xOffset, yOffset);
    }
}

@end
13
stu

UIRefreshControlのフレームは自動的に管理されるため、その位置を変更しようとすると、予期しない結果(特にiOS SDKバージョン間)が発生する可能性があります。お気づきのように、コントロールは常にスーパービューのフレームの水平方向の中央に配置されます。これを知っていると、スーパービューを相殺することで状況を「活用」できます。

あなたのケースでは、テーブルビューのフレームをCGRect(-40, 0, 360, superViewHight)に設定します。これにより、テーブルビューがウィンドウの左側の40ポイントに配置されます。したがって、テーブルビューのコンテンツをそれに応じて調整して、40ポイント右に配置するか、余分な40ポイントを拡張する必要がありますが、画面からレンダリングされるものはパディングになるはずです。

これを行うと、UIRefreshControlは中央に配置されるため、必要に応じて左に20ポイント移動します。

enter image description here

4
Chris Wagner
- (UIRefreshControl *)refreshControl
{
    if (!_refreshControl)
    {
        _refreshControl = [UIRefreshControl new];
        _refreshControl.tintColor = [UIColor lightGrayColor];

_refreshControl.bounds = CGRectInset(_refreshControl.bounds、0.0、10.0); //差し込み10.0で下げます

        [_refreshControl addTarget:self
                            action:@selector(pullToRefresh)
                  forControlEvents:UIControlEventValueChanged];
    }
    return _refreshControl;
}
1

Swift 2.2の場合、解は

let offset = -50

let refreshControl = UIRefreshControl()
refreshControl.bounds = CGRect(x: refreshControl.bounds.Origin.x, y: offset,
                               width: refreshControl.bounds.size.width,
                               height: refreshControl.bounds.size.height)
refreshControl.attributedTitle = NSAttributedString(string: "Pull to refresh")
refreshControl.addTarget(self, action: #selector(networking), forControlEvents: UIControlEvents.ValueChanged)
self.profileTable.addSubview(refreshControl)

それでおしまい。

1
muhasturk

SwiftバージョンはWerewolfが提案した回避策に似ています。私は独自のカスタムアクティビティビュークラス(MyCustomActivityIndicatorView)を使用しており、更新コントロールのサブビューでもあるため、フレームは変更せず、デフォルトのサブビューのフレームのみを使用します。layoutSubviewsをsuperで呼び出した後、カスタムアクティビティビューのフレームを調整して一致させます。これはすべてカスタムUIRefreshControlサブクラス。

override func layoutSubviews() {

    for view in subviews {
        if view is MyCustomActivityIndicatorView {
            continue
        } else {
            // UIRefreshControl sizes itself based on the size of it's subviews. Since you can't remove the default refresh indicator, we modify it's frame to match our activity indicator before calling layoutSubviews on super
            var subFrame = view.frame
            subFrame.size = activityView.intrinsicContentSize()

            // add some margins
            subFrame.offsetInPlace(dx: -layoutMargins.left, dy: -layoutMargins.top)
            subFrame.insetInPlace(dx: -(layoutMargins.left+layoutMargins.right), dy: -(layoutMargins.top+layoutMargins.bottom))

            view.frame = subFrame.integral
        }
    }

    super.layoutSubviews()

    activityView.frame = bounds
}

注:UIViewのレイアウトマージンを追加しますが、これは厳密には必要ありませんが、アクティビティインジケーターにある程度のスペースを与えます。

0
Ben Lachman

UIScrollViewをサブクラス化する必要があります。次のコードは、UIInfreshControlの場所をcontentInsetに基づいて調整します(垂直スクロールでのみ機能しますが、水平スクロールで簡単に採用できます)

override public func layoutSubviews() {
    super.layoutSubviews()
    guard let refreshControl = self.refreshControl else { return }

    var newFrame = refreshControl.frame

    if contentInset.top > .zero {
        let yOffset = abs(contentInset.top + contentOffset.y)

        newFrame.Origin.y = -contentInset.top - yOffset
        newFrame.size.height = yOffset
    }

    guard newFrame != refreshControl.frame else { return }
    refreshControl.frame = newFrame
}
0