我试图在带有很多 subview 的 ScrollView 顶部添加一个“ float 按钮”。单击该按钮时,UINavigation Controller 会提示出现一个新的 viewController。当我关闭 Controller ,返回到原来的 viewController 时,我希望按钮仍然在那里!
为了不处理约束冲突,我的解决方案是将 UIButton 添加到 UIWindow。
[UIApplication.sharedApplication.keyWindow addSubview:_myButton];
一切正常。但问题是当我关闭新 Controller 以返回到包含按钮的 Controller 时:
[self dismissViewControllerAnimated:YES completion:nil];
该按钮不会立即“出现”。只有当动画完成后(viewController 完全下降),按钮才会“重新出现”。如果我通过设置摆脱动画:
[self dismissViewControllerAnimated:NO completion:nil];
一切顺利!该按钮立即就在那里。但我真的很想保留这个动画。
我想知道是否有办法让按钮留在 viewController 上,或者至少在动画完全完成之前出现,使其看起来像屏幕上的实际 float 按钮。
如果这是不可能的,是否有另一种方法可以在 iOS 上本地构建 float 按钮,而无需安装任何额外的 pod?
谢谢!
最佳答案
这是一个非常简单的示例。
- 为主视图添加 ScrollView
- 向 ScrollView 添加内容
- 将按钮添加到主视图 - 不添加到 ScrollView
- 限制 ScrollView 右上角的按钮
- 为按钮添加触摸操作以呈现另一个 View Controller
因为我们将按钮添加为 ScrollView 的同级(而不是 subview ),所以它将“ float ”在 ScrollView 的前面,并且 ScrollView 的内容将在其后面滚动。
当我们呈现 - 然后关闭 - 另一个 VC 时,“ float 按钮”不会去任何地方,因此当我们返回主 VC 时它仍然可见。
初始 View :
在按钮“后面”滚动查看内容:
查看实际效果的代码:
ViewController.h
//
// ViewController.h
// OCSept2019
//
// Created by Don Mag on 9/12/19.
//
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end
ViewController.c
//
// ViewController.m
// OCSept2019
//
// Created by Don Mag on 9/12/19.
//
#import "ViewController.h"
#import "AnotherViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// instantiate a scroll view
UIScrollView *scrollView = [UIScrollView new];
scrollView.translatesAutoresizingMaskIntoConstraints = NO;
scrollView.backgroundColor = [UIColor cyanColor];
// instantiate a stack view
UIStackView *stackView = [UIStackView new];
stackView.translatesAutoresizingMaskIntoConstraints = NO;
stackView.axis = UILayoutConstraintAxisVertical;
stackView.alignment = UIStackViewAlignmentFill;
stackView.distribution = UIStackViewDistributionFill;
stackView.spacing = 40.0;
// add 20 labels as arrangeed subview of the stack view
for (int i = 0; i < 20; i++) {
UILabel *v = [UILabel new];
v.backgroundColor = [UIColor yellowColor];
v.text = [NSString stringWithFormat:@"This is label %ld", (long)i + 1];
v.textAlignment = NSTextAlignmentCenter;
[stackView addArrangedSubview:v];
}
// add the stack view as a subview of the scroll view
[scrollView addSubview:stackView];
// add the scroll view as a subview of self.view
[self.view addSubview:scrollView];
[NSLayoutConstraint activateConstraints:
@[
// constrain the scroll view to all 4 sides of self.view (safe area), with 20-pts "padding"
[scrollView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor constant: 20.0],
[scrollView.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor constant: -20.0],
[scrollView.leadingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.leadingAnchor constant: 20.0],
[scrollView.trailingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.trailingAnchor constant: -20.0],
// constrain the stack view to all 4 sides of the scroll view, with
// 8-pts left and right "padding"
// 40-pts top and bottom "padding"
[stackView.topAnchor constraintEqualToAnchor:scrollView.topAnchor constant: 40.0],
[stackView.bottomAnchor constraintEqualToAnchor:scrollView.bottomAnchor constant: -40.0],
[stackView.leadingAnchor constraintEqualToAnchor:scrollView.leadingAnchor constant: 8.0],
[stackView.trailingAnchor constraintEqualToAnchor:scrollView.trailingAnchor constant: -8.0],
// constrain stack view width equal to scroll view width - 16 (to account for 8-pt padding on each side)
[stackView.widthAnchor constraintEqualToAnchor:scrollView.widthAnchor constant:-16.0],
]
];
// instantiate a button with Red background
UIButton *b = [UIButton new];
b.translatesAutoresizingMaskIntoConstraints = NO;
[b setTitle:@"Tap to Present Another VC" forState:UIControlStateNormal];
b.backgroundColor = [UIColor redColor];
[b setTitleColor:[UIColor lightGrayColor] forState:UIControlStateHighlighted];
// add the button as a subview of self.view
// this will place it *in front of* the scroll view
[self.view addSubview:b];
// constrain it at upper-right corner of the scroll view
[NSLayoutConstraint activateConstraints:
@[
[b.topAnchor constraintEqualToAnchor:scrollView.topAnchor constant:8.0],
[b.trailingAnchor constraintEqualToAnchor:scrollView.trailingAnchor constant:-8.0],
]
];
// add a touch up inside action
[b addTarget:self action:@selector(btnTap) forControlEvents:UIControlEventTouchUpInside];
}
- (void) btnTap {
// instantiate another view controller
AnotherViewController *vc = [AnotherViewController new];
// present it
[self presentViewController:vc animated:YES completion:nil];
}
@end
AnotherViewController.h
//
// AnotherViewController.h
// OCSept2019
//
// Created by Don Mag on 9/12/19.
//
#import <UIKit/UIKit.h>
@interface AnotherViewController : UIViewController
@end
另一个ViewController.m
//
// AnotherViewController.m
// OCSept2019
//
// Created by Don Mag on 9/12/19.
//
#import "AnotherViewController.h"
@interface AnotherViewController ()
@end
@implementation AnotherViewController
- (void)viewDidLoad {
[super viewDidLoad];
// green background
self.view.backgroundColor = [UIColor greenColor];
// instantiate a button with Blue background
UIButton *b = [UIButton new];
b.translatesAutoresizingMaskIntoConstraints = NO;
[b setTitle:@"Tap to Dismiss" forState:UIControlStateNormal];
b.backgroundColor = [UIColor blueColor];
[b setTitleColor:[UIColor lightGrayColor] forState:UIControlStateHighlighted];
// add it as a subview of self.view
[self.view addSubview:b];
// constrain it centered X and Y
[NSLayoutConstraint activateConstraints:
@[
[b.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor],
[b.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor],
]
];
// add a touch up inside action
[b addTarget:self action:@selector(btnTap) forControlEvents:UIControlEventTouchUpInside];
}
- (void) btnTap {
// dismiss this view controller
[self dismissViewControllerAnimated:YES completion:nil];
}
@end
关于ios - 如何向 UIWindow 添加 subview 并防止其在使用 UINavigationController 转换时消失?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57908965/