Добавить представление в виде таблицы (UITableViewController)
Ситуация: У меня есть UITableViewController, загружающий некоторые данные асинхронно из службы. За это время я хотел бы разместить полный экран (кроме навигационной панели) над табличным представлением, показывающим мой пользовательский индикатор и текст.
Проблема: Проблема, с которой я сталкиваюсь, заключается в том, что когда мой пользовательский вид (с красным фоном) помещается поверх UITableView, строки в виде таблицы отображаются через мой пользовательский вид (см. ниже).
Что я пробовал:
Я пытался использовать insertBelow и выше, не работал. Я также попытался сделать: tableview.Hidden = true, но это также скрывает пользовательский вид по какой-либо причине, как видно на изображении 2.
![See lines]()
Image1: По какой-то причине я вижу, что строки бросали мой взгляд.
![Hidden true]()
Изображение 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 ();
}
Ответы
Ответ 1
Проблема заключается в том, что представление a UITableViewController
является UITableView
, поэтому вы не можете добавлять subviews к контроллеру поверх таблицы.
Я бы рекомендовал переключиться с UITableViewController
на простой UIViewController
, содержащий UITableView
. Таким образом, основной вид контроллера - это простой UIView
, который содержит таблицу, и вы можете добавить subviews в основной UIView
, и они будут помещены поверх табличного представления.
Ответ 2
Вы можете использовать self.navigationController.view
как представление для добавления subview.
Ответ 3
Вы можете попытаться добавить представление в окно, а не вставить его в виде таблицы следующим образом:
UIWindow* mainWindow = [[UIApplication sharedApplication] keyWindow];
[mainWindow addSubview: overlayview];
Ответ 4
UIWindow* window = [[UIApplication sharedApplication].delegate.window;
[window addSubview: your-overlayview];
Ответ 5
Решение Swift/Storyboard
Примечание. В приведенном ниже коде предполагается, что у пользователя есть настраиваемый вид (ratingView в моем случае), который должен быть представлен через UITableView.
Я прочитал много ответов на этот вопрос и похожие вопросы на SO. Другие ответы из этих источников работали в разной степени для меня (например, просмотр загружен, но не показан или недоступен,...). Я использую Swift 2.0+, и я использую полное решение для этого, используя UITableViewController.
Создайте выход в панель навигации и представление, которое вы хотите вызвать над табличным представлением.
//MARK:Outlets
@IBOutlet weak var navBar:UINavigationBar!
@IBOutlet var ratingView: MNGStarRating!
В моем случае я также хотел анимировать представление по представлению таблицы, поэтому я использовал переменную класса для хранения ссылки на точку перегиба и точку над сценой (вне экрана).
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
}
Предостережения
Мой просмотр - это пользовательский вид в раскадровке (сидя за пределами tableview, но подключен к контроллеру TableView). Представление имеет требуется атрибут пользовательской среды выполнения layer.zPosition
с установленным значением 2 (это гарантирует, что он отображается перед UITableView).
Можно также попробовать сыграть с помощью метода bringSubviewToFront: и sendSubviewToBack: методы, если вы не хотите устанавливать zPosition (Я думаю, что zPosition проще использовать)
![2]()
![3]()
Ответ 6
Попробуйте подключить кнопку внизу TableViewController
объявить кнопку как переменную
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)
}