16

情况:我有一个 UITableViewController 从服务异步加载一些数据。在此期间,我想在表格视图上放置一个全屏(导航栏除外)视图,以显示我的自定义指示器和文本。

问题:我面临的问题是,当我的自定义视图(它具有红色背景)放置在 UITableView 上时,表格视图的线条通过我的自定义视图显示(见下图)。

我尝试了什么: 我尝试使用 insertBelow 及以上,但没有用。我也尝试这样做:tableview.Hidden = true,但这也出于某种原因隐藏了自定义视图,如图 2 所示。

看线

Image1:出于某种原因,我可以看到线条投掷了我的视线。

隐藏真实

图 2:Tableview + 自定义视图在 hidden = true 使用时消失。

我的代码:

        public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();

        UIView view = new UIView (new RectangleF (0, 0, this.TableView.Frame.Width, this.TableView.Frame.Height));
        view.BackgroundColor = UIColor.Red;

        this.TableView.AddSubview (view);

        TableView.Source = new SessionTableViewSource ();
    }
4

7 回答 7

49

您可以self.navigationController.view用作添加子视图的视图。

于 2014-09-17T12:51:42.677 回答
38

问题是 a 的 ViewUITableViewController是 a UITableView,因此您不能将子视图添加到表顶部的控制器中。

我建议从 a 切换UITableViewControllerUIViewController包含UITableView. 这样,控制器主视图是一个UIView包含表格的普通视图,您可以向主视图添加子视图UIView,它们将被放置在表格视图的顶部。

于 2013-09-03T15:59:05.627 回答
3

您可以尝试将视图添加到窗口而不是将其嵌套在表视图中,如下所示:

UIWindow* mainWindow = [[UIApplication sharedApplication] keyWindow];
[mainWindow addSubview: overlayview];
于 2013-09-02T17:00:51.913 回答
2
UIWindow* window = [[UIApplication sharedApplication].delegate.window;
[window addSubview: your-overlayview];
于 2013-12-25T08:56:03.360 回答
2

Swift / 故事板解决方案

注意:下面的代码假设有一个自定义视图(在我的例子中是 ratingView),该视图将在 UITableView 上呈现。

我已经阅读了许多关于 SO 和类似问题的答案。这些来源的其他答案对我来说在不同程度上起作用(例如,视图已加载但未显示或无法访问,...)。我正在使用 Swift 2.0+,我正在分享使用UITableViewController执行此操作的完整解决方案。

创建一个到导航栏和视图的出口,你想把它带到 tableview 上。

//MARK:Outlets
@IBOutlet weak var navBar:UINavigationBar!
@IBOutlet var ratingView: MNGStarRating!

在我的例子中,我还想为 tableview 上的视图设置动画,所以我使用一个类变量来保存对拐点的引用和场景上方的一个点(屏幕外)。

var centerYInflection:NSLayoutConstraint!
var aPointAboveScene = -(max(UIScreen.mainScreen().bounds.width,UIScreen.mainScreen().bounds.height) * 2.0)

然后,viewDidLoad我调用了一个函数(configureRatingViewAutoLayout),它为要在表格视图上设置动画的新视图配置和添加约束。

func configureRatingViewAutoLayout() {
    //REQUIRED    
    self.navBar.superview?.addSubview(self.ratingView)

    var newConstraints:[NSLayoutConstraint] = []
    newConstraints.append(self.ratingView.leadingAnchor.constraintEqualToAnchor(self.view.leadingAnchor,constant: 10)) 
    newConstraints.append(self.ratingView.trailingAnchor.constraintEqualToAnchor(self.view.trailingAnchor,constant: 10))
    newConstraints.append(self.ratingView.centerXAnchor.constraintEqualToAnchor(self.view.centerXAnchor))

    //hides the rating view above the scene
    self.centerYInflection = self.ratingView.centerYAnchor.constraintEqualToAnchor(self.view.centerYAnchor, constant: self.aPointAboveScene)

    //the priority must be set below 1000 if you intend to change it after it has been added to a view
    self.centerYInflection.priority = 750
    newConstraints.append(self.centerYInflection)

    //constraints must be added to the container view of the two items
    self.ratingView.superview?.addConstraints(newConstraints)

}

Nota Bene - 在 UITableViewController 上;self.view 是 self.tableView。他们指向相同的东西,所以我想也可以使用上面的 self.tableView 参考。

一段时间后...为了响应 UIControl 事件,我调用此方法。

@IBAction func toggleRatingView (sender:AnyObject?){

    //REQUIRED
    self.ratingView.superview?.layoutIfNeeded()

    UIView.animateWithDuration(1.0, delay: 0.0, usingSpringWithDamping: 0.37, initialSpringVelocity: 0.99, options: [.CurveEaseOut], animations: { () -> Void in

        if CGRectContainsRect(self.view.frame, self.ratingView.frame) {

            //in frame ~ animate away
            //I play a sound to alert the user something is happening 

            self.centerYInflection.constant = self.aPointAboveScene
            self.centerYInflection.priority = UILayoutPriority(950)
            //I disable portions of the UI
            self.disableUIElements(nil)



        } else {

            //out of frame ~ animate in
            //I play a different sound here                

            self.centerYInflection.constant = 0
            self.centerYInflection.priority = UILayoutPriority(950)

            //I enable the UI fully
            self.enableUIElements(nil)


        }
        //REQUIRED
        self.ratingView.superview?.setNeedsLayout()
        self.ratingView.superview?.layoutIfNeeded()


        }) { (success) -> Void in

            //do something else

    }

}

这些辅助方法可以配置为在视图呈现期间控制对场景中元素的访问。

func disableUIElements(sender:AnyObject?) {
    //UI

}
func enableUIElements(sender:AnyObject?) {

    //UI

}

注意事项

我的视图是 Storyboard 中的自定义视图(位于 tableview 之外但连接到 TableView 控制器)。该视图有一个 必需的用户运行时属性layer.zPosition,其数值设置为 2(这确保它显示在 UITableView 的前面)。

如果您不想设置 zPosition,也可以尝试使用 bringSubviewToFront: 和 sendSubviewToBack: 方法(我认为 zPosition 更易于使用)

2

3

于 2015-12-11T17:37:51.703 回答
1

试试这个钩子底部的按钮UITableViewController

将按钮声明为变量:

var submitButton: UIButton!

并在viewDidLoad

submitButton = UIButton(frame: CGRect(x: 5, y: UIScreen.main.bounds.size.height - 50, width: UIScreen.main.bounds.size.width - 10, height: 50))        
submitButton.backgroundColor = UIColor.init(red: 180/255, green: 40/255, blue: 56/255, alpha: 1.0)
submitButton.setTitle("Submit", for: .normal)
submitButton.titleLabel?.font = UIFont(name: "Arial", size: 15)
submitButton.titleLabel?.textColor = .white
submitButton.addTarget(self, action: #selector(submit), for: .touchUpInside)
submitButton.layer.cornerRadius = 5        
self.view.addSubview(submitButton)

并实现这个方法:

override func scrollViewDidScroll(_ scrollView: UIScrollView) {
  submitButton.frame = CGRect.init(x: submitButton.frame.origin.x, y: UIScreen.main.bounds.size.height + scrollView.contentOffset.y - 50, width: submitButton.frame.width, height: submitButton.frame.height)
}
于 2017-12-25T11:56:27.013 回答
0

这对我有用:

if let myTopView = Bundle.main.loadNibNamed("MyTopView", owner: self, options: nil)?.first as? MyTopView {

        if let view = UIApplication.shared.keyWindow{
            view.addSubview(myView);
            myTopView.translatesAutoresizingMaskIntoConstraints = false

            myTopView.topAnchor.constraint(equalTo: view.topAnchor ).isActive = true
            myTopView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
            myTopView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
            myTopView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true

        }

    }
于 2020-05-11T19:45:13.137 回答