Jon*_*and 30 iphone objective-c uitabbarcontroller uitableview ios
点击当前导航控制器的标签栏图标已经将用户返回到根视图,但如果它们向下滚动,如果再次点击它我想要它滚动到顶部(与点击状态栏相同的效果).我该怎么做?
一个很好的例子是Instagram的feed,向下滚动然后点击标签栏中的主页图标以滚动回到顶部.
滚动回到顶部很容易,但将它连接到标签栏控制器是我坚持的.
Dru*_*erB 36
实现用户选择选项卡时要通知的UITabBarControllerDelegate方法tabBarController:didSelectViewController:.即使已选择该选项卡,再次点击相同的选项卡按钮时也会调用此方法.
实现这个的好地方delegate可能是你的AppDelegate.或逻辑上"拥有"标签栏控制器的对象.
我会声明并实现一个可以在视图控制器上调用的方法来滚动UICollectionView.
- (void)tabBarController:(UITabBarController *)tabBarController
didSelectViewController:(UIViewController *)viewController
{
static UIViewController *previousController = nil;
if (previousController == viewController) {
// the same tab was tapped a second time
if ([viewController respondsToSelector:@selector(scrollToTop)]) {
[viewController scrollToTop];
}
}
previousController = viewController;
}
Run Code Online (Sandbox Code Playgroud)
小智 21
SWIFT 3
开始..
首先UITabBarControllerDelegate在类中实现,并确保在viewDidLoad中设置委托
class DesignStoryStreamVC: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UITabBarControllerDelegate {
@IBOutlet weak var collectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
self.tabBarController?.delegate = self
collectionView.delegate = self
collectionView.dataSource = self
}
}
Run Code Online (Sandbox Code Playgroud)
接下来,将此委托函数放在您的类中的某个位置.
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
let tabBarIndex = tabBarController.selectedIndex
print(tabBarIndex)
if tabBarIndex == 0 {
self.collectionView.setContentOffset(CGPoint.zero, animated: true)
}
}
Run Code Online (Sandbox Code Playgroud)
确保在"if"语句中选择正确的索引.我包含了打印功能,因此您可以仔细检查.
您可以使用shouldSelect而不是didSelect,这样就不需要外部变量来跟踪前一个视图控制器。
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
if ([viewController isEqual:self] && [tabBarController.selectedViewController isEqual:viewController]) {
// Do custom stuff here
}
return YES;
}
Run Code Online (Sandbox Code Playgroud)
Swift 5:不需要在UITabBarController.
在MyTabBarController.swift 中,实现tabBarController(_:shouldSelect)检测用户何时重新选择标签栏项:
protocol TabBarReselectHandling {
func handleReselect()
}
class MyTabBarController: UITabBarController, UITabBarControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
delegate = self
}
func tabBarController(
_ tabBarController: UITabBarController,
shouldSelect viewController: UIViewController
) -> Bool {
if tabBarController.selectedViewController === viewController,
let handler = viewController as? TabBarReselectHandling {
// NOTE: viewController in line above might be a UINavigationController,
// in which case you need to access its contents
handler.handleReselect()
}
return true
}
}
Run Code Online (Sandbox Code Playgroud)
在MyTableViewController.swift 中,通过将 table view 滚动到顶部来处理重新选择:
class MyTableViewController: UITableViewController, TabBarReselectHandling {
func handleReselect() {
tableView?.setContentOffset(.zero, animated: true)
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您只需实现TabBarReselectHandling.
我正在使用此View层次结构.
UITabBarController > UINavigationController > UIViewController
我有一个参考UITabBarController的UIViewController
tabBarControllerRef = self.tabBarController as! CustomTabBarClass
tabBarControllerRef!.navigationControllerRef = self.navigationController as! CustomNavigationBarClass
tabBarControllerRef!.viewControllerRef = self
Run Code Online (Sandbox Code Playgroud)
然后我创建了一个Bool在正确的时间调用的方法,以及一个允许滚动到顶部的方法
var canScrollToTop:Bool = true
// Called when the view becomes available
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
canScrollToTop = true
}
// Called when the view becomes unavailable
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
canScrollToTop = false
}
// Scrolls to top nicely
func scrollToTop() {
self.collectionView.setContentOffset(CGPoint(x: 0, y: 0), animated: true)
}
Run Code Online (Sandbox Code Playgroud)
然后在我的UITabBarController自定义类我调用了这个
func tabBarController(tabBarController: UITabBarController, didSelectViewController viewController: UIViewController) {
// Allows scrolling to top on second tab bar click
if (viewController.isKindOfClass(CustomNavigationBarClass) && tabBarController.selectedIndex == 0) {
if (viewControllerRef!.canScrollToTop) {
viewControllerRef!.scrollToTop()
}
}
}
Run Code Online (Sandbox Code Playgroud)
结果与Instagram和Twitter的Feed相同:)
extension UIViewController {
func scrollToTop() {
func scrollToTop(view: UIView?) {
guard let view = view else { return }
switch view {
case let scrollView as UIScrollView:
if scrollView.scrollsToTop == true {
scrollView.setContentOffset(CGPoint(x: 0.0, y: -scrollView.contentInset.top), animated: true)
return
}
default:
break
}
for subView in view.subviews {
scrollToTop(view: subView)
}
}
scrollToTop(view: self.view)
}
}
Run Code Online (Sandbox Code Playgroud)
这是我在Swift 3中的答案。它使用辅助函数进行递归调用,并自动滚动到调用顶部。在嵌入在UITabBarController中嵌入的UINavigationController中的UICollectionViewController上测试
小智 5
Swift 3 方法::
//MARK: Properties
var previousController: UIViewController?
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
if self.previousController == viewController || self.previousController == nil {
// the same tab was tapped a second time
let nav = viewController as! UINavigationController
// if in first level of navigation (table view) then and only then scroll to top
if nav.viewControllers.count < 2 {
let tableCont = nav.topViewController as! UITableViewController
tableCont.tableView.setContentOffset(CGPoint(x: 0.0, y: -tableCont.tableView.contentInset.top), animated: true)
}
}
self.previousController = viewController;
return true
}
Run Code Online (Sandbox Code Playgroud)
这里有一些注意事项:“shouldSelect”而不是“didSelect”,因为后者是在转换之后发生的,这意味着 viewController 本地变量已经改变了。2. 我们需要在改变控制器之前处理事件,以便获得关于滚动(或不滚动)动作的导航视图控制器的信息。
说明:: 如果当前视图实际上是一个列表/表格视图控制器,我们要滚动到顶部。如果导航已经前进并且我们点击相同的标签栏,则所需的操作是仅弹出一个步骤(默认功能)而不是滚动到顶部。如果导航没有进步意味着我们仍然在表格/列表控制器中,只有这样我们才想在再次点击时滚动到顶部。(Facebook 在从用户的个人资料中点击“Feed”时所做的事情也是如此。它只会返回到 Feed 而不会滚动到顶部。
| 归档时间: |
|
| 查看次数: |
18721 次 |
| 最近记录: |