【问题标题】:UITableView with UIRefreshControl under a semi-transparent status bar半透明状态栏下带有 UIRefreshControl 的 UITableView
【发布时间】:2012-10-06 11:09:29
【问题描述】:

我创建了一个 UITableView,我想在我的半透明黑色状态栏下方滚动。在我的 XIB 中,我只是将表格视图的 y 位置设置为 -20,一切看起来都很好。

现在,我刚刚添加了一个下拉刷新 iOS6 UIRefreshControl,但是由于 -20 y 位置,它可以从状态栏后面拖动。我希望它的“拉伸到”位置位于状态栏下方而不是后面。

它为什么会搞砸是有道理的,但改变它的框架和表格视图的内容插入等似乎没有任何区别。

文档建议,一旦设置了 refreshControl,UITableViewController 就会从那时起处理它的位置。

有什么想法吗?

【问题讨论】:

    标签: iphone objective-c ios uitableview uirefreshcontrol


    【解决方案1】:

    您可以将UIRefreshControl 子类化并像这样实现layoutSubviews

    @implementation RefreshControl {
        CGFloat topContentInset;
        BOOL topContentInsetSaved;
    }
    
    - (void)layoutSubviews {
        [super layoutSubviews];
    
        // getting containing scrollView
        UIScrollView *scrollView = (UIScrollView *)self.superview;
    
        // saving present top contentInset, because it can be changed by refresh control
        if (!topContentInsetSaved) {
            topContentInset = scrollView.contentInset.top;
            topContentInsetSaved = YES;
        }
    
        // saving own frame, that will be modified
        CGRect newFrame = self.frame;
    
        // if refresh control is fully or partially behind UINavigationBar
        if (scrollView.contentOffset.y + topContentInset > -newFrame.size.height) {
            // moving it with the rest of the content
            newFrame.origin.y = -newFrame.size.height;
    
        // if refresh control fully appeared
        } else {
            // keeping it at the same place
            newFrame.origin.y = scrollView.contentOffset.y + topContentInset;
        }
    
        // applying new frame to the refresh control
        self.frame = newFrame;
    }
    

    它会考虑 tableView 的 contentInset,但您可以将 topContentInset 变量更改为您需要的任何值,其余部分将由它处理。

    我希望代码有足够的文档记录以了解其工作原理。

    【讨论】:

    • 像魅力一样工作。谢谢安东尼!
    【解决方案2】:

    只需继承 UIRefreshControl 并像这样覆盖 layoutSubviews:

    - (void)layoutSubviews
    {
        UIScrollView* parentScrollView = (UIScrollView*)[self superview];
    
        CGSize viewSize = parentScrollView.frame.size;
    
        if (parentScrollView.contentInset.top + parentScrollView.contentOffset.y == 0 && !self.refreshing) {
            self.hidden = YES;
        } else {
            self.hidden = NO;
        }
    
        CGFloat y = parentScrollView.contentOffset.y + parentScrollView.scrollIndicatorInsets.top + 20;
    
        self.frame = CGRectMake(0, y, viewSize.width, viewSize.height);
    
        [super layoutSubviews];
    }
    

    【讨论】:

    • 这段代码没有考虑到UIRefreshControl正在移动和扩展,而不仅仅是随scrollView一起移动。
    • 我添加了一些代码来考虑最初的“下拉”,现在它看起来应该很好:)。
    【解决方案3】:

    current upvoted answer 不能很好地配合您将组件拉下的事实(正如 Anthony Dmitriyev 指出的那样),偏移量不正确。最后一部分是修复它。

    无论哪种方式:使用以下方法子类化UIRefreshControl

    - (void)layoutSubviews
    {
        UIScrollView* parentScrollView = (UIScrollView*)[self superview];
        CGFloat extraOffset = parentScrollView.contentInset.top;
    
        CGSize viewSize = parentScrollView.frame.size;
    
        if (parentScrollView.contentInset.top + parentScrollView.contentOffset.y == 0 && !self.refreshing) {
            self.hidden = YES;
        } else {
            self.hidden = NO;
        }
    
        CGFloat y = parentScrollView.contentOffset.y + parentScrollView.scrollIndicatorInsets.top + extraOffset;
    
        if(y > -60 && !self.isRefreshing){
            y = -60;
        }else if(self.isRefreshing && y <30)
        {
            y = y-60;
        }
        else if(self.isRefreshing && y >=30)
        {
            y = (y-30) -y;
        }
    
        self.frame = CGRectMake(0, y, viewSize.width, viewSize.height);
    
        [super layoutSubviews];
    }
    

    【讨论】:

    • 为什么要写这行代码y = (y-30) -y;打开括号后它将是 y = 30;据了解,它应该是 y = y - 30
    【解决方案4】:

    UIRefreshControl 始终位于UITableView 中的内容之上。如果您需要更改 refreshControl 的位置,请尝试更改 tableView 的顶部contentInsetUIRefreshControl 在确定应放置的位置时会考虑到这一点。

    【讨论】:

    • 是的,我试过了。它只影响内容,不影响刷新控制:(
    • 同样的问题,我的 UITableView 有一个 inset UIEdgeInsets inset = UIEdgeInsetsMake(37, 0, 0, 0); tblAccounts.contentInset = 插图;但是 refreshControl 忽略了插图
    【解决方案5】:

    试试这个:

    CGFloat offset = 44;
    for (UIView *subview in [self subviews]) {
        if ([subview isKindOfClass:NSClassFromString(@"_UIRefreshControlDefaultContentView")]) {
            NSLog(@"Setting offset!");
            [subview setFrame:CGRectMake(subview.frame.origin.x, subview.frame.origin.y + offset, subview.frame.size.width, subview.frame.size.height)];
        }
    }
    

    这会将 UIRefreshControll 向下移动 44 个点;

    【讨论】:

      【解决方案6】:

      我发现覆盖其他答案中的 layoutsubviews 不仅仅改变了框架,它们还改变了行为(控件开始随着内容向下滑动)。为了改变框架而不是我这样做的行为:

      - (void)layoutSubviews {
          [super layoutSubviews];
      
          CGRect frame = self.frame;
          CGFloat desiredYOffset = 50.0f;
          self.frame = CGRectMake(frame.origin.x, frame.origin.y + desiredYOffset, frame.size.width, frame.size.height);
      

      }

      【讨论】:

        【解决方案7】:

        这运行起来超级流畅,但它是一个超级 hacky 的解决方案:

        class CustomUIRefreshControl: UIRefreshControl {
            
            override func layoutSubviews() {
                let offset = UIApplication.shared.windows[0].safeAreaInsets.top
                frame = CGRect(
                    x: frame.origin.x,
                    y: frame.origin.y + offset/2.5,
                    width: frame.size.width,
                    height: frame.size.height
                )
                
                let attribute = [
                    NSAttributedString.Key.font: UIFont(name: "Chalkduster", size: offset/2)!,
                    NSAttributedString.Key.foregroundColor: UIColor.clear
                ]
                attributedTitle = NSAttributedString(string: "Hack", attributes: attribute)
        
                super.layoutSubviews()
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-04-01
          • 1970-01-01
          • 2011-02-22
          • 1970-01-01
          • 1970-01-01
          • 2014-08-19
          • 2017-08-28
          相关资源
          最近更新 更多