it-swarm.com.ru

Добавить представление над таблицей (UITableViewController)

Ситуация: У меня есть UITableViewController, загружающий некоторые данные асинхронно из службы. В течение этого времени я хотел бы разместить полноэкранный (кроме панели навигации) вид таблицы, показывающий мой пользовательский индикатор и текст. 

Проблема: Проблема, с которой я сталкиваюсь, заключается в том, что, когда мое пользовательское представление (у него красный фон) помещается поверх UITableView, линии табличного представления отображаются через мое пользовательское представление (см. Изображение ниже). 

Что я пытался: Я пытался использовать insertBelow и выше, не работает. Я также попытался сделать: tableview.Hidden = true, но это также по какой-то причине скрывает пользовательский вид, как показано на рисунке 2.

See lines

Изображение 1: Почему-то я вижу, как линии бросают мой взгляд.

Hidden true

Изображение 2: Tableview + пользовательский вид исчез, когда скрыто = 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 ();
    }
13
Mittchel

Проблема в том, что представление UITableViewController является UITableView, поэтому вы не можете добавить подпредставления к контроллеру в верхней части таблицы.

Я бы рекомендовал переключиться с UITableViewController на простую UIViewController, которая содержит UITableView. Таким образом, основное представление контроллера представляет собой простую UIView, содержащую таблицу, и вы можете добавить подпредставления к основной UIView, и они будут размещены поверх табличного представления.

31
redent84

Вы можете использовать self.navigationController.view как представление для добавления подпредставления.

40
sagus_helgy

Вы можете попытаться добавить представление в окно вместо того, чтобы вложить его в представление таблицы следующим образом: 

UIWindow* mainWindow = [[UIApplication sharedApplication] keyWindow];
[mainWindow addSubview: overlayview];
3
jonas vermeulen

Решение 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). В представлении есть required атрибут времени выполнения пользователя, определенный layer.zPosition со значением Number, установленным на 2 (это гарантирует, что он представлен перед UITableView). 

Можно также попытаться поиграть с помощью метода visibleSubviewToFront: и sendSubviewToBack: методы, если вы не хотите устанавливать zPosition (Я думаю, что zPosition проще в использовании)

 2

 3

2
Tommie C.
UIWindow* window = [[UIApplication sharedApplication].delegate.window;
[window addSubview: your-overlayview];
2
jianpx

Попробуйте подключить кнопку внизу 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)
}
1
Sh_Khan