通过tableview添加视图(UITableViewController)
情况:我有一个UITableViewController从一个服务asynchronous加载一些数据。 在此期间,我想放置一个全屏幕(除了导航栏)视图在表视图显示我的自定义指标和文字。
问题:我面临的问题是,当我的自定义视图(它有一个红色的背景)被放置在UITableView的表视图的行通过我的自定义视图(见下图)显示。
我尝试过:我试图使用insertBelow和以上,没有工作。 我也试过:tableview.Hidden = true,但是由于某些原因,这也隐藏了自定义视图,如图2所示。
Image1:出于某种原因,我可以看到线条抛出了我的视野。
图2:当隐藏=真使用时,Tableview +自定义视图消失。
我的代码:
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 (); }
问题是UITableViewController
的视图是一个UITableView
,所以你不能添加子视图到控制器的顶部。
我build议从UITableViewController
切换到包含UITableViewController
的简单UIViewController
。 这样,控制器的主视图是一个普通的UIView
,它包含一个表格,你可以将子视图添加到主UIView
并将它们放置在表格视图的顶部。
你可以使用self.navigationController.view
作为添加子视图的视图。
您可以尝试将视图添加到窗口中,而不是将其嵌套在表格视图中,如下所示:
UIWindow* mainWindow = [[UIApplication sharedApplication] keyWindow]; [mainWindow addSubview: overlayview];
UIWindow* window = [[UIApplication sharedApplication].delegate.window; [window addSubview: your-overlayview];
Swift / Storyboard解决scheme
注意:下面的代码假设有一个自定义视图(在我的情况下为ratingView),将在UITableView上呈现。
我已经阅读了很多关于这个和类似的问题的答案。 这些来源的其他答案在不同程度上为我工作(例如,查看加载,但没有显示或不可访问,…)。 我使用的是Swift 2.0+,我正在使用UITableViewController共享完整的解决scheme。
创build一个导航栏和视图,你想要通过tableview的出口。
//MARK:Outlets @IBOutlet weak var navBar:UINavigationBar! @IBOutlet var ratingView: MNGStarRating!
在我的情况下,我也希望在tableview中为视图添加animation,所以我使用了一个类variables来保存对拐点的引用以及场景之上的一个点(off-screen)。
var centerYInflection:NSLayoutConstraint! var aPointAboveScene = -(max(UIScreen.mainScreen().bounds.width,UIScreen.mainScreen().bounds.height) * 2.0)
然后在viewDidLoad
我调用了一个函数(configureRatingViewAutoLayout),它configuration并添加新视图的约束,使其在桌面视图上animation化。
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 } }
这些辅助方法可以configuration为在视图呈现期间控制对场景中元素的访问。
func disableUIElements(sender:AnyObject?) { //UI } func enableUIElements(sender:AnyObject?) { //UI }
注意事项
我的视图是故事板中的一个自定义视图(坐在TableView之外,但连接到TableView控制器)。 该视图有一个必要的用户运行时属性定义
layer.zPosition
与数值设置为2(这确保它出现在UITableView前面)。你也可以尝试玩bringSubviewToFront:和sendSubviewToBack:方法,如果你不想设置zPosition(我认为zPosition更容易使用)
试试这个钩住一个TableViewController底部的button
声明button作为一个variables
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) }