Programing

현재 UITableViewController 위에 UIView를 추가하는 방법

lottogame 2021. 1. 5. 07:39
반응형

현재 UITableViewController 위에 UIView를 추가하는 방법


UITableViewController의 viewDidLoad 메서드 내에서 하위 뷰 (UIView)를 추가하는 데 어려움이 있습니다.

이것은 작동합니다 :

[self.view addSubview:self.progView];

그러나 UIView progView를 통해 표 셀 라인이 번지는 것을 볼 수 있습니다.

이 접근 방식을 시도했습니다.

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

현재보기 위의 superview에 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가 나타나지만 테이블 뒤에있는 것 같습니다.


위의 접근 방식을 시도했지만 작동하지 않았습니다. 또한 테이블보기를 처음부터 설정해야하므로 구성과 코드가 너무 많이 필요하다는 사실도 발견했습니다 (스토리 보드 내에서 쉽게 수행 할 수있는 작업).

대신 UITableView 위에 추가하려는 뷰를 UITableViewController의 UINavigationController의 뷰에 추가했습니다.

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

이 방법을 사용하려면 UINavigationController에 UITableViewController를 포함해야하지만 탐색 컨트롤러를 원하지 않더라도이 방법을 사용하고 탐색 모음을 숨길 수 있습니다.


이것은 실제로 가능하고 쉽습니다. 약간의 재배 선이 필요합니다. 비슷한 상황이 발생하여 테이블 뷰 상단에로드 화면을 추가 할 수 있도록이를 코딩했습니다. 이 접근 방식을 사용하면 자신의 콘텐츠에 정적 테이블 셀을 사용할 수도 있습니다.

컨트롤러가 Storyboard 또는 XIB의 UITableViewController이고 기존 테이블보기를 유지하면서 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까지 기다려야합니다. 이 시점 이후에 접근자는 올바른 UIViewUITableView.

사용법 : 같은 것

    [self.view addSubview:myView];

테이블 뷰의 내용으로 스크롤 myView하지 않고 테이블 뷰 앞에 UIView 추가합니다 myView.

참고 : 이 답변은 솔루션에 경계선 역설적 코드가 포함되어 있다는 지적 후에 편집되었습니다. UITableViewController는 보유한 참조에 대해 이상한 일을합니다. 좀 더 신중한 테스트가이 간단한 대답을 도출했습니다. :)


uiviewcontroller 포함을 사용하여 uitableviewcontroller 위에 하위보기를 추가 할 수있었습니다.

UITableViewController는 실제로 정적 셀과 관련하여 매우 편리하며 "just use uitableview"라는 일반적인 대답이 실제로 실행 가능하지 않을 수있는 유일한 경우 일 것입니다.

그래서 이것이 제가하는 방법입니다.

  1. 제공하여 있는 UITableViewController 스토리 보드 식별자 즉 MyStaticTableView
  2. 새로운 UIViewController 하위 클래스를 만들고 이름을 UITableViewControllerContainer 라고합니다.
  3. 스토리 보드 내부의 UITableViewController 대신이 컨트롤러를 배치 합니다.
  4. 새 컨트롤러에 하위보기를 추가하고 " view_container " 와 같은 콘센트에 연결합니다.
  5. 당신에 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];
}

발생할 수있는 문제 :

  1. 추가 상단 공간이있는 경우 UITableViewController에 "wants fullscreen"플래그를 추가해야합니다.
  2. UITableViewControllerContainer에서 제대로 크기가 조정되지 않는 경우

코드 추가 :

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

이 시점에서 UITableViewController에서 컨테이너 뷰에 직접 액세스 할 수 있습니다.

self.view.superview.superview

추가 한 내용은 테이블 뷰 컨트롤러 위에 표시됩니다.


뷰 레이어의 zPosition을 늘릴 수 있습니다.

이렇게하면 다른 뷰 위에 표시됩니다 (기본적으로 zPosition이 0과 같음).

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

스위프트 2018

스토리 보드를 사용하는 방법은 다음과 같습니다.

1) 스토리 보드에보기를 추가합니다.
여기에 이미지 설명 입력

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) 짜잔!
여기에 이미지 설명 입력

보기는 테이블보기와 함께 스크롤되지 않습니다. 스토리 보드에서 쉽게 디자인 할 수 있습니다.

참고 : 이 솔루션은 탐색 컨트롤러에 하위보기를 추가하고 여기에서 탐색 아래에있는 다른 화면으로 이동하는 경우이 하위보기가 지속되는 것을 발견하고 segue를 수행하는 동안 viewDidDisappear에서 copyrightView.removeFromSuperView를 사용하여 제거합니다.


UITableViewController는 UIViewController의 하위 클래스이므로 원하는 뷰를 수퍼 뷰에 추가해야합니다.

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

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

문제는의 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];
}

그런 다음 하위보기를 추가해야하는 경우 self.tableView적절하게 아래 또는 위에 추가하십시오 .

또 다른 옵션은 UIViewController필요한 작업을 수행 하는 하위 클래스 를 만드는 것입니다. UITableViewController솔직히 그다지 많이 추가하지 않으며 구현하는 작은 기능은 쉽게 복제됩니다. 작업을 매우 쉽게 수행하는 방법을 설명하는 코드 재사용을 늘리기위한 Recreating UITableViewController 와 같은 기사가 있습니다.


비슷한 문제가 있었고 아래 코드를 사용하여 해결했습니다.

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

스택에있는 컨트롤러를 사용하여 올바른 위치에 뷰를 삽입합니다.


Apple 예제 "iPhoneCoreDataRecipes"는 NIB를 사용하여 헤더를 UITableView에로드합니다. 참조 여기 :


표 위에 이미지를 추가했습니다. 이 코드를 사용했습니다.

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

신속한 솔루션 (Daniel Saidi와 동일) :

컨트롤러가 Storyboard 또는 XIB의 UITableViewController이고 기존 테이블보기를 유지하면서 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)
}

Storyboard 또는 XIB 파일에서 : UITableViewController의 tableView를 tableViewReference 변수에 연결합니다.

그러면 다음과 같이 하위보기를 추가 할 수 있습니다.

self.view.addSubView(someView)

iOS 11 용 업데이트 :

이제 UITableView안전 영역에 AutoLayout 제약 조건을 사용할 때 Subview를 추가 할 수 있습니다 . 이러한 뷰는 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]
]];

viewDidAppear에 다음 코드를 입력하면됩니다.

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

시험: [self.view bringSubviewToFront:self.progView];

또는 self.progView테이블보기 에 추가 할 수 있습니다.


To keep UIView above table view in UITableViewController I'm using one(or more) of delegate methods (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) { ... }

As views can only have one superview that seams too be good solution, correct me if I'm wrong. Still getting 60fps so it's fine for me.


Swift 4

This is the most simplified version of a number of answers here where we are recomposing the view hierarchy. This approach does not require additional outlets for storyboards / nibs and will also work with programmatically constructed instances.

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)

    }

}

There may be reasons not to do this, but this works for me so far. If you use an ap

Inside viewDidLayoutSubviews you can run this, but make sure to only run it once obviously

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

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's window object to add the custom view on top of the view controller
    [delegate.window addSubview: loadingView]; 
}

다음과 같이 시도하십시오.

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

참조 URL : https://stackoverflow.com/questions/4641879/how-to-add-a-uiview-above-the-current-uitableviewcontroller

반응형