状況: UITableViewControllerがサービスから非同期でデータをロードしています。この間、全画面(ナビゲーションバーを除く)のビューをテーブルビューの上に配置して、カスタムインジケーターとテキストを表示します。
問題:私が直面している問題は、カスタムビュー(赤い背景)がUITableViewの上に置かれると、テーブルビューの線がカスタムビューを通して表示されることです(下の画像を参照)。 。
私が試したこと: insertBelow以上を使用しようとしましたが、機能しませんでした。私も試しました:tableview.Hidden = trueですが、これにより、画像2にあるように、何らかの理由でカスタムビューも非表示になります。
画像1:何らかの理由で、線が私の見解を投げているのを見ることができます。
画像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 ();
}
問題は、UITableViewController
のビューがUITableView
であるため、テーブルの上にあるコントローラーにサブビューを追加できないことです。
UITableViewController
から、UIViewController
を含む単純なUITableView
に切り替えることをお勧めします。このように、コントローラのメインビューはテーブルを含むプレーンなUIView
であり、サブビューをメインUIView
に追加すると、テーブルビューの上に配置されます。
サブビューを追加するためのビューとしてself.navigationController.view
を使用できます。
次のように、テーブルビューにネストする代わりに、ビューをウィンドウに追加することができます。
UIWindow* mainWindow = [[UIApplication sharedApplication] keyWindow];
[mainWindow addSubview: overlayview];
注:以下のコードは、UITableViewで表示されるカスタムビュー(私の場合はratingView)があることを前提としています。
これに対する多くの回答と 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の前に表示されます)。ZPositionを設定したくない場合は、bringSubviewToFront:メソッドとsendSubviewToBack:メソッドをいじってみることもできます(zPositionの方が使いやすいと思います)。
UIWindow* window = [[UIApplication sharedApplication].delegate.window;
[window addSubview: your-overlayview];
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)
}