webentwicklung-frage-antwort-db.com.de

Ansicht über Tableview hinzufügen (UITableViewController)

Situation: Ich habe einen UITableViewController, der einige Daten asynchron von einem Dienst lädt. Während dieser Zeit möchte ich eine Vollbildansicht (außer der Navigationsleiste) über der Tabellenansicht platzieren, die meinen benutzerdefinierten Indikator und Text zeigt. 

Problem: Das Problem, mit dem ich konfrontiert bin, ist, dass, wenn meine benutzerdefinierte Ansicht (sie hat einen roten Hintergrund) über der UITableView platziert wird, die Zeilen der Tabellenansicht durch meine benutzerdefinierte Ansicht angezeigt werden (siehe Abbildung unten). 

Was ich versucht habe: Ich habe versucht, insertBelow und höher zu verwenden, funktionierte nicht. Ich habe auch versucht zu tun: tableview.Hidden = true, aber dies verbirgt auch die benutzerdefinierte Ansicht aus irgendeinem Grund, wie in Bild 2 zu sehen.

See lines

Bild1: Aus irgendeinem Grund kann ich sehen, dass die Linien meine Sicht geworfen haben.

Hidden true

Bild 2: Tableview + benutzerdefinierte Ansicht ist weg, wenn hidden = true verwendet wird.

Mein Code:

        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

Das Problem ist, dass die Ansicht eines UITableViewControllerein UITableViewist. Daher können Sie dem Controller nicht über der Tabelle Subviews hinzufügen.

Ich würde empfehlen, von UITableViewControllerzu einem einfachen UIViewControllerzu wechseln, der einen UITableViewenthält. Auf diese Weise ist die Hauptansicht des Controllers eine einfache UIViewname__, die eine Tabelle enthält, und Sie können dem Haupt UIViewUnteransichten hinzufügen. Diese werden dann über der Tabellenansicht platziert.

31
redent84

Sie können self.navigationController.view als Ansicht zum Hinzufügen einer Unteransicht verwenden.

40
sagus_helgy

Sie können versuchen, die Ansicht zum Fenster hinzuzufügen, anstatt sie in der Tabellenansicht wie folgt zu verschachteln: 

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

Swift/Storyboard-Lösung

Hinweis: Bei dem folgenden Code wird davon ausgegangen, dass eine benutzerdefinierte Ansicht (RatingView in meinem Fall) vorhanden ist, die über eine UITableView dargestellt werden soll.

Ich habe viele Antworten auf diese und ähnliche Fragen zu SO gelesen. Die anderen Antworten aus diesen Quellen funktionierten für mich in unterschiedlichem Maße (z. B. Ansicht geladen, aber nicht gezeigt oder nicht zugänglich, ...). Ich verwende Swift 2.0+ und teile die komplette Lösung mit UITableViewController .

Erstellen Sie einen Auslass für die Navigationsleiste und die Ansicht, die Sie über die Tabellenansicht bringen möchten. 

//MARK:Outlets
@IBOutlet weak var navBar:UINavigationBar!
@IBOutlet var ratingView: MNGStarRating!

In meinem Fall wollte ich auch die Ansicht über die Tabellenansicht animieren. Daher verwendete ich eine Klassenvariable, um einen Verweis auf den Wendepunkt und einen Punkt über der Szene (außerhalb des Bildschirms) zu halten.

var centerYInflection:NSLayoutConstraint!
var aPointAboveScene = -(max(UIScreen.mainScreen().bounds.width,UIScreen.mainScreen().bounds.height) * 2.0)

Dann habe ich in viewDidLoad eine Funktion (configureRatingViewAutoLayout) aufgerufen, die die Einschränkungen für die neue Ansicht konfiguriert und hinzufügt, die über die Tabellenansicht animiert werden soll.

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 - Auf einem UITableViewController; die self.view ist die self.tableView. Sie zeigen auf dasselbe, also könnte man auch Oben die Referenz self.tableView verwenden.

Etwas später ... Als Reaktion auf ein UIControl-Ereignis rufe ich diese Methode auf.

@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

    }

}

Diese Hilfsmethoden können so konfiguriert werden, dass der Zugriff auf Elemente in Ihrer Szene während der Präsentation der Ansicht gesteuert wird. 

func disableUIElements(sender:AnyObject?) {
    //UI

}
func enableUIElements(sender:AnyObject?) {

    //UI

}

Vorsichtsmaßnahmen

Meine Ansicht ist eine benutzerdefinierte Ansicht im Storyboard (die sich außerhalb der Tabellenansicht Befindet, jedoch mit dem TableView-Controller verbunden ist). In der Ansicht ist ein required user Laufzeitattribut definiert layer.zPosition mit einem auf 2 eingestellten Number-Wert (dies stellt sicher, dass es vor der UITableView dargestellt wird). 

Man könnte auch versuchen, mit bringSubviewToFront: Und sendSubviewToBack: -Methoden herumzuspielen, wenn man nicht die zPosition Festlegen möchte (ich denke, zPosition ist einfacher zu benutzen)

 2

 3

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

Versuchen Sie dies, um einen Button am unteren Rand der UITableViewController anzuhängen.

button als Variable deklarieren:

var submitButton: UIButton!

und in 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)

und implementiere diese Methode:

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