Подтвердить что ты не робот

Как добавить UIView над текущим UITableViewController

Мне трудно добавить subview (UIView) из метода viewDidLoad для UITableViewController

Это работает:

[self.view addSubview:self.progView];

Но вы можете видеть, как линии ячейки таблицы истекают через прогист UIView.

Я пробовал этот подход:

[self.view.superview insertSubview:self.progView aboveSubview:self.view];

Какая попытка добавить progView, UIView в супервизор, над текущим представлением. Когда я пытаюсь это сделать, UIView никогда не появляется.

- ОБНОВЛЕНИЕ -

Ниже приведена последняя попытка:

UIView *myProgView = (UIView *)self.progView; //progView is a method that returns a UIView

[self.tableView insertSubview:myProgView aboveSubview:self.tableView]; 
[self.tableView bringSubviewToFront:myProgView];

Результат совпадает с [self.view addSubview: self.progView]; UIView появляется, но, по-видимому, за столом.

4b9b3361

Ответ 1

Я попробовал подход выше, но не получил его работать. Я также обнаружил, что для этого требуется слишком много настроек и кода, поскольку для этого требуется настроить представление таблицы с нуля (что легко сделать изнутри раскадровки).

Вместо этого я добавил представление, которое я хотел добавить выше своего UITableView в представление UINavigationController UITableViewController, как таковое:

[self.navigationController.view addSubview:<view to add above the table view>];

Этот подход требует, чтобы вы включили UITableViewController в UINavigationController, но даже если вам не нужен контроллер навигации, вы все равно можете использовать этот подход и просто скрыть панель навигации.

Ответ 2

Это на самом деле вполне возможно и просто - для этого требуется просто переделка. Я столкнулся с подобной ситуацией и закодировал это, чтобы позволить мне добавлять экраны загрузки поверх моих табличных представлений. Этот подход также позволяет использовать статические ячейки таблицы с вашим собственным контентом.

Если ваш контроллер является UITableViewController в раскадровке или XIB, и вы хотите переназначить self.view на стандартный UIView, сохранив существующий вид таблицы:

Добавьте эти переменные экземпляра в заголовочный файл :

IBOutlet UITableView *tableViewReference; // to keep a reference to the tableview
UIView *viewReference; // a reference to the new background view

В вашем файле раскадровки или XIB: Подключите tableView в UITableViewController к переменной tableViewReference.

Затем в вашем файле реализации:

// Override the default accessors of the tableview and view
- (UITableView*)tableView { return tableViewReference; }
- (UIView*)view { return viewReference; }

- (void)viewDidLoad
{
    [super viewDidLoad];

    // instantiate the new self.view, similar to the tableview
    viewReference = [[UIView alloc] initWithFrame:tableViewReference.frame];
    [viewReference setBackgroundColor:tableViewReference.backgroundColor];
    viewReference.autoresizingMask = tableViewReference.autoresizingMask;
    // add it as a subview
    [viewReference addSubview:tableViewReference];

    /* remainder of viewDidLoad */

}

Хотя это может показаться странным, UITableViewController делает много причудливых вещей со ссылками за кулисами. Вам нужно дождаться viewDidLoad, чтобы сделать своп. После этой точки аксессоры будут указывать на правильные UIView и UITableView.

Использование: Что-то вроде

    [self.view addSubview:myView];

добавит UIView myView перед представлением таблицы без прокрутки myView с содержимым представления таблицы.

Примечание.. Этот ответ был отредактирован после того, как было указано, что решение содержит пограничный парадоксальный код. UITableViewController делает странные вещи для ссылок, которые он имеет. Более тщательное тестирование получило этот более простой ответ:)

Ответ 3

Ive смог добавить subview поверх uitableviewcontroller с помощью утилиты uiviewcontroller.

UITableViewController на самом деле очень удобен, когда дело доходит до статических ячеек, и это, вероятно, единственный раз, когда общий ответ "просто использовать uitableview" может фактически не быть жизнеспособным.

Так вот как я это делаю.

  • предоставить UITableViewController идентификатор StoryBoard, т.е. MyStaticTableView
  • создайте новый подкласс UIViewController и назовите его UITableViewControllerContainer
  • разместите этот контроллер вместо своего UITableViewController внутри раскадровки
  • добавьте subview к новому контроллеру и привяжите его к выходу под названием " view_container"
  • на вас UITableViewControllerContainer метод viewDidLoad

добавить код вроде:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    UITableViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:@"MyStaticTableView"];
    [self addChildViewController:vc];
    [self.view_container addSubview:vc.view];
}

Проблемы, которые могут возникнуть у вас:

  • Если у вас есть дополнительное верхнее пространство, обязательно добавьте флажок "хочет полноэкранный режим" в ваш UITableViewController
  • если он не будет правильно изменен в вашем UITableViewControllerContainer

добавить код:

- (void)viewWillAppear:(BOOL)animated
{
    [[self.view_container.subviews lastObject] setFrame:self.view.frame];
}

в этот момент из вашего UITableViewController вы можете получить доступ к виду контейнера непосредственно с помощью

self.view.superview.superview

и все, что вы добавите к нему, будет отображаться сверху вашего контроллера табличного представления.

Ответ 4

Вы можете увеличить zPosition слоя вашего представления.

Это приведет к отображению над другими представлениями (которые по умолчанию имеют значение zPosition, равное 0)

self.progView.layer.zPosition++;
[self.view addSubview:self.progView];

Ответ 5

Swift 2018

Вот мой путь с раскадровкой:

1) Добавить вид в раскадровку.
enter image description here

2) Свяжите его с классом UITableViewController:

@IBOutlet weak var copyrightLabel: UILabel!

3) Добавьте это в коде

self.navigationController?.view.addSubview(copyrightView)
copyrightView.frame = CGRect(x: 0,
                            y: self.view.bounds.size.height - copyrightView.bounds.size.height,
                            width: self.view.bounds.size.width,
                            height: copyrightView.bounds.size.height)

4) Вуаля!
enter image description here

Представление не будет прокручиваться вместе с представлением таблицы. Это может быть легко разработано от раскадровки.

ПРИМЕЧАНИЕ. Это решение добавляет подпредставление к контроллеру навигации, и если вы собираетесь перейти к другому экрану, находящемуся далее вниз по навигационной панели, вы увидите, что это подпредставление сохраняется, удалите его, используя copyrightView.removeFromSuperView для viewDidDisappear во время выполнения segue.

Ответ 6

Проблема заключается в том, что свойство view UITableViewController идентично свойству tableView. Это означает, что корневой вид всегда является контроллером табличного представления, и все, что добавлено в качестве подвью, будет подчиняться функциональности представления таблиц. У этого есть другие нежелательные побочные эффекты, такие как прокрутки вашего подпрограммы, когда вы не можете их хотеть.

Здесь есть пара вариантов. Вы можете переопределить loadView и установить свой собственный вид и представление таблицы:

// note: untested
- (void)loadView {
    self.view = [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
    self.view.backgroundColor = [UIColor whiteColor];

    UITableView *tblView = [[UITableView alloc]
        initWithFrame:CGRectZero
        style:UITableViewStylePlain
    ];

    tblView.autoresizingMask =
        UIViewAutoresizingFlexibleWidth |
        UIViewAutoresizingFlexibleHeight
    ;

    self.tableView = tblView;
    [self.view addSubview:tblView];
    [tblView release];
}

И затем, когда вам нужно добавить subview, добавьте его ниже или выше self.tableView, если это необходимо.

Другим вариантом является создание подкласса UIViewController, который делает то, что вам нужно. UITableViewController честно не добавляет этого, и небольшая функциональность, которую он реализует, легко реплицируется. Есть такие статьи, как Воспроизведение UITableViewController для увеличения повторного использования кода, которые объясняют, как это сделать довольно легко.

Ответ 7

У меня была схожая проблема, и я решил ее решить, используя ниже код:

     [self.navigationController.view insertSubview:<subview> 
       belowSubview:self.navigationController.navigationBar];

Это вставляет вид в правильном месте с помощью контроллеров, присутствующих в Stack.

Ответ 8

Поскольку UITableViewController является подклассом UIViewController, вам нужно добавить свой вид в свой супервизор.

Swift:
self.view.superview?.addSubview(viewTobeAdded)

Objective C:
[self.view.superview addSubview: viewTobeAdded];

Ответ 9

Пример Apple "iPhoneCoreDataRecipes" использует NIB для загрузки заголовка в UITableView. См. здесь:

Ответ 10

Я добавил изображение над таблицей. Я использовал этот код:

self.tableView.tableHeaderView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"header.png"]];

Ответ 11

Решение для быстрых (эквивалентно Даниэлю Сайди):

Если ваш контроллер является UITableViewController в раскадровке или XIB, и вы хотите переназначить self.view на стандартный UIView, сохранив существующий вид таблицы:

@IBOutlet var tableViewReference: UITableView!
var viewReference: UIView!

Затем в вашем файле реализации:

Добавьте эти переменные экземпляра в файл контроллера табличного представления:

override var tableView: UITableView! {
    get { return tableViewReference }
    set { super.tableView = newValue }
}

override var view: UIView! {
    get { return viewReference }
    set { super.view = newValue }
}

override func viewDidLoad() {
    super.viewDidLoad()
    self.edgesForExtendedLayout = UIRectEdge.None
    self.extendedLayoutIncludesOpaqueBars = false
    self.automaticallyAdjustsScrollViewInsets = false

    //rewiring views due to add tableView as subview to superview
    viewReference = UIView.init(frame: tableViewReference.frame)
    viewReference.backgroundColor = tableViewReference.backgroundColor
    viewReference.autoresizingMask = tableViewReference.autoresizingMask
    viewReference.addSubview(tableViewReference)
}

В вашем файле раскадровки или XIB: подключите tableView в UITableViewController к переменной tableViewReference.

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

self.view.addSubView(someView)

Ответ 12

Обновление для iOS 11:

Теперь возможно добавить Subview к UITableView при использовании ограничений AutoLayout в безопасной области. Эти представления не будут прокручиваться вдоль TableView.

Этот пример помещает представление ниже панели навигации поверх UITableView UITableViewController

[self.tableView addSubview:self.topBarView];
[NSLayoutConstraint activateConstraints:@[
    [self.topBarView.topAnchor constraintEqualToAnchor:self.tableView.safeAreaLayoutGuide.topAnchor],
    [self.topBarView.leadingAnchor constraintEqualToAnchor:self.tableView.safeAreaLayoutGuide.leadingAnchor],
    [self.topBarView.trailingAnchor constraintEqualToAnchor:self.tableView.safeAreaLayoutGuide.trailingAnchor],
    [self.topBarView.heightAnchor constraintEqualToConstant:40.0]
]];

Ответ 13

попробуйте: [self.view bringSubviewToFront:self.progView];

Или вы можете попробовать добавить self.progView в свой вид таблицы.

Ответ 14

Вы можете просто поместить следующий код в viewDidAppear:

[self.tableView.superview addSubview:<your header view>];

Ответ 15

Чтобы сохранить UIView над табличным представлением в UITableViewController, я использую один (или несколько) методов делегата (UITableViewDelegate).

override func viewDidLoad() {
    super.viewDidLoad()
    self.tableView.addSubview(headerView)
}

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    tableView.addSubview(overlayView) // adds view always on top
}
// if using footers in table view
tableView(_ tableView: UITableView, willDisplayFooterView view: UIView, forSection section: Int) { ... }

Поскольку у взглядов может быть только один просмотр, что швы тоже будут хорошим решением, исправьте меня, если я ошибаюсь. Все еще получаю 60 кадров в секунду, так что это хорошо для меня.

Ответ 16

Swift 4

Это наиболее упрощенная версия ряда ответов, где мы перекомпоновываем иерархию представлений. Этот подход не требует дополнительных выходов для раскадровок/перьев, а также будет работать с программно созданными экземплярами.

class MyTableViewController: UITableViewController {

    var strongTableView: UITableView?

    override var tableView: UITableView! {
        get {
            return strongTableView ?? super.tableView
        }
        set {
            strongTableView = newValue
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // theoretically we could use self.tableView = self.tableView but compiler will not let us assign a property to itself
        self.tableView = self.view as? UITableView
        self.view = UIView(frame: self.tableView!.frame)
        self.view.addSubview(tableView)

    }

}

Ответ 17

У меня была аналогичная проблема, когда я хотел добавить индикатор загрузки поверх моего UITableViewController. Чтобы решить эту проблему, я добавил UIView в качестве подвид окна. Это решило проблему. Вот как я это сделал.

-(void)viewDidLoad{
    [super viewDidLoad];
    //get the app delegate
    XYAppDelegate *delegate = [[UIApplication sharedApplication] delegate];

    //define the position of the rect based on the screen bounds
    CGRect loadingViewRect = CGRectMake(self.view.bounds.size.width/2, self.view.bounds.size.height/2, 50, 50);
    //create the custom view. The custom view is a property of the VIewController
    self.loadingView = [[XYLoadingView alloc] initWithFrame:loadingViewRect];
    //use the delegate window object to add the custom view on top of the view controller
    [delegate.window addSubview: loadingView]; 
}

Ответ 18

Могут быть причины не делать этого, но это работает для меня до сих пор. Если вы используете ap

Внутри viewDidLayoutSubviews вы можете запустить это, но обязательно запустите его только один раз

self.searchTableView = [[UITableView alloc] initWithFrame:self.tableView.frame style:UITableViewStylePlain];
self.searchTableView.backgroundColor = [UIColor purpleColor];
[self.view.superview addSubview:self.searchTableView];

Ответ 19

попробуйте что-то вроде этого:

[self.tableView addSubview:overlayView];
overlayView.layer.zPosition = self.tableView.backgroundView.layer.zPosition + 1;