如何在Google地点自动完成控制器(GMSAutocompleteViewController)中设置文本?该问题涉及到IT技术。

9
我需要帮助在我的应用程序中打开GMSAutocompleteViewController时设置搜索栏中的文本。 我正在Google Place AutocompleteViewController中使用GMSAutocompleteViewController

enter image description here

8个回答

11

我通过将@Youngjin和@Exception对Swift 4和Google Places 2.6.0的回答结合起来,得到了一个可行的解决方案。

要访问GMSAutocompleteViewController搜索栏:

let views = gmsAutoCompleteViewController.view.subviews
let subviewsOfSubview = views.first!.subviews
let subOfNavTransitionView = subviewsOfSubview[1].subviews
let subOfContentView = subOfNavTransitionView[2].subviews     
let searchBar = subOfContentView[0] as! UISearchBar

然后设置文本 并自动搜索

searchBar.text = "Your address"
searchBar.delegate?.searchBar?(searchBar, textDidChange: "Your address") // This performs the automatic searching.

我发现当我试图在didRequestAutocompletePredictions(_ viewController: GMSAutocompleteViewController)中设置文本时,会收到EXC_BAD_ACCESS错误。

所以我改为将这段代码放入展示自动完成功能的完成块中,这样就可以正常运行了。

将所有内容组合在一起:

let gmsAutoCompleteViewController = GMSAutocompleteViewController()
gmsAutoCompleteViewController.delegate = self

present(gmsAutoCompleteViewController, animated: true) {
    let views = gmsAutoCompleteViewController.view.subviews
    let subviewsOfSubview = views.first!.subviews
    let subOfNavTransitionView = subviewsOfSubview[1].subviews
    let subOfContentView = subOfNavTransitionView[2].subviews
    let searchBar = subOfContentView[0] as! UISearchBar
    searchBar.text = "Your address"
    searchBar.delegate?.searchBar?(searchBar, textDidChange: "Your address")
}

编辑:我发现这个解决方案似乎只适用于iOS 11。 let searchBar = subOfContentView [0] as!UISearchBar 在iOS 10及可能更低版本上会失败。


1
谢谢兄弟,解决方案太棒了! - Bohdan Savych
我在iOS 10中遇到了以下代码崩溃:let searchBar = subOfContentView[0] as! UISearchBar。你能否告诉我低版本的替代方法? - priya.vr
由于gmsAutoCompleteViewController.view.subviews.count = 0,无法在iOS 12上工作。 - Олександр Бабіч

6

@Cools

在Swift 3中,看起来有不同的层次结构。我已经深入探究了VC并找到了位置。

func didRequestAutocompletePredictions(_ viewController: GMSAutocompleteViewController) {
    let views = viewController.view.subviews
    let subviewsOfSubview = views.first!.subviews
    let subOfNavTransitionView = subviewsOfSubview[1].subviews
    let subOfContentView = subOfNavTransitionView[2].subviews
    let searchBar = subOfContentView[0] as! UISearchBar
    searchBar.text = "YOUR_TEXT"
}

然而它有一个缺点,就是不能自动搜索。等我找到解决方案后,我会再次编辑。

完美的解决方案! - mudin

6

好的,我不一定建议这种做法,因为如果你想要更多控制,你应该使用UISearchResultsController。但是,这里有一个更加流畅的版本:

//Where viewController is the GMSAutocompleteViewController
if let searchBar = (viewController.view.subviews
   .flatMap { $0.subviews }
   .flatMap { $0.subviews }
   .flatMap { $0.subviews }
   .filter { $0 == $0 as? UISearchBar}).first as? UISearchBar {
            searchBar.text = "YOUR_TEXT_HERE"
            searchBar.delegate?.searchBar?(searchBar, textDidChange: "YOUR_TEXT_HERE") // to get the autoComplete Response

    }

这种方法的好处是你不需要精确地知道SearchBar的位置。它基本上尝试将所有子视图压成一个数组,并从中过滤掉SearchBar。如果Google决定改变SearchBar隐藏的位置,这种方法仍然可以找到它。问题是你仍然需要知道有多少级子视图。可能会有一个递归函数来处理这个问题。

1
感谢您提供的解决方案,虽然我理解您对搜索栏位置的担忧,但目前它的工作正常(Y)。我们可以使用searchBar.delegate?.searchBar?(searchBar, textDidChange: "Your address")来获取自动完成响应。 - Mohit G.

4

我发现这里的解决方案在iOS 10上不起作用。因此,我编写了递归方法来查找具体视图 - UISearchBar,在我们的情况下:

extension UIView {
    func getViewWithConcreteType<T: UIView>()-> T? {
        if let concreteSubview = self as? T {
            return concreteSubview
        }

        for subview in subviews {
            let concreteView: T? = subview.getViewWithConcreteType()
            if concreteView != nil {
                return concreteView!
            }
        }

        return nil
    }
}

我做了一些对原始解决方案的修改:
let views = autocompleteController.view.subviews
            let subviewsOfSubview = views.first!.subviews
            let subOfNavTransitionView = subviewsOfSubview[1].subviews
            let subOfContentView = subOfNavTransitionView[2].subviews

            if let searchBar = subOfContentView[0] as? UISearchBar {
                searchBar.text = text
                searchBar.delegate?.searchBar?(searchBar, textDidChange: text)
            } else {
                let searchBar: UISearchBar? = autocompleteController.view.getViewWithConcreteType()
                searchBar?.text = text
                searchBar.map { $0.delegate?.searchBar?($0, textDidChange: text) }
            }

2
您可以使用类似以下方式向此搜索栏注入文本:
func injectTextInSearchView(_ text: String, _ view: UIView) {
    if let view = view as? UISearchBar {
        view.text = text
        view.delegate?.searchBar!(view, textDidChange: text)
        return
    }
    for subview in view.subviews {
        injectTextInSearchView(text, subview)
    }
}

2
- (void)viewDidLoad {
    [super viewDidLoad];

    acController = [[GMSAutocompleteViewController alloc] init];

    acController.delegate = self;
}

- (IBAction)btnSearch1:(id)sender {
    [self presentViewController:acController animated:YES completion:nil];
}

- (void)didRequestAutocompletePredictions:(GMSAutocompleteViewController *)viewController {
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

    UIView *Views = viewController.view;

    NSArray *Aar2 = [[Views subviews][0] subviews];

    UIView *View2 = Aar2[1];

    UIView *View3 = [View2 subviews][2];

    UISearchBar *Search = [[View3 subviews] firstObject];

    Search.text = @"Your text";

    [Search.delegate searchBar:Search textDidChange:txtAddress.text];
}

// 酷爱的人们


1
我对Swift编码不是很熟悉,但根据文档 - 自定义文本和背景颜色
您可以设置自动完成 UI 控件中所有文本和背景的颜色,以使小部件更符合您的应用程序的视觉外观。有两种方法可以设置 UI 控件颜色:
- 通过使用本机 iOS UIAppearance 协议 尽可能全局地样式化 UI 控件。这些设置适用于许多但不是所有的 UI 控件元素。 - 通过使用小部件类上的 SDK 方法设置不受 UIAppearance 协议 支持的属性。
文档说明搜索栏文本颜色、搜索栏色调颜色和搜索栏占位符文本颜色(默认搜索文本)可使用(UIAppearance 协议或 SDK 方法)进行样式设置。
希望这些信息能够帮助您。

1
抱歉,我无法提供翻译,因为您没有提供要翻译的具体内容。 - Wasim Ahmed

0
typedef void (^TTSearchBarHandler)(UISearchBar * searchbar);


__weak UIViewController *weaks = self;
[self searchSubviews:viewController.view completion:^(UISearchBar *searchbar) {

    if(searchbar){          
        [searchbar.delegate searchBar:searchbar textDidChange:@"Your Text"];
    }
}];


-(void)searchSubviews:(UIView*)view completion:(TTSearchBarHandler)completion{
    
    if([view isKindOfClass:[UISearchBar class]]){
        UISearchBar *searchBar = (UISearchBar*)view;
        if(completion){
            completion(searchBar);
        }
    }
    else{
        for(UIView * subview in view.subviews){
            [self searchSubviews:subview completion:^(UISearchBar *searchbar) {
                if(completion){
                    completion(searchbar);
                }
            }];
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接