Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UISearchBar cannot display #1270

Closed
bolasblack opened this issue May 14, 2015 · 11 comments
Closed

UISearchBar cannot display #1270

bolasblack opened this issue May 14, 2015 · 11 comments
Labels
Resolution: Locked This issue was locked by the bot.

Comments

@bolasblack
Copy link

My Obj-C Code:

    #import <UIKit/UIKit.h>
    #import "RCTViewManager.h"

    @interface RCTSearchBarTest : RCTViewManager
    @end

    @implementation RCTSearchBarTest

    RCT_EXPORT_MODULE()

    - (UISearchBar *)view
    {
      return [[UISearchBar alloc] init];
    }

    @end

My js code:

    var {requireNativeComponent} = React;
    var RCTSearchBarTest = requireNativeComponent('RCTSearchBarTest', null);
    var App = React.createClass({
      render: function() {
        <View>
          <RCTSearchBarTest />
        </View>
      }
    })

I learned it from React-Native's document: https://facebook.github.io/react-native/docs/nativecomponentsios.html

I tried Reveal, the UISearchBar is exist, but not displayed.

After I add code [searchBar setFrame:CGRectMake(0, 0, 375, 44)];, it works, but I lookup from React-Native's code I didn't found anything like this.

Actual code: CoffeeScript, Objective-C

Is anything I missed?

@umhan35
Copy link
Contributor

umhan35 commented May 14, 2015

Some native components are using ComponentHeight provided from Obj-C code.

Before anyone comes here, you can search ComponentHeight in this repo. The height for DatePicker and SegmentedControl is explicitly set just like what you did.

@bolasblack
Copy link
Author

@umhan35 I tried the way you said, not work for me :(

@umhan35
Copy link
Contributor

umhan35 commented May 15, 2015

It will be something looks like this:

In your Obj-C code:

- (NSDictionary *)constantsToExport
{
  RCTSearchBar *view = [[RCTSearchBar alloc] init];
  return @{
           @"ComponentHeight": @(view.intrinsicContentSize.height),
           };
}

JS:

NativeModules = require('NativeModules');

...

style={{height: NativeModules.SearchBarManager.ComponentHeight}}

...

@bolasblack
Copy link
Author

@umhan35 You can see my code: CoffeeScript, Objective-C, I have tried this :(

@umhan35
Copy link
Contributor

umhan35 commented May 15, 2015

Try my one. Mine works before I post it. Try to use the dirty inline style.

@bolasblack
Copy link
Author

@umhan35 I tried just now, but nothing changed :'(

@brentvatne
Copy link
Collaborator

@umhan35's approach seems solid - check out the RCTDatePickerManager for an example of how this can be done

@bolasblack
Copy link
Author

I found the reason:

image

The UIView and UISearchBarBackground frame size become 0, 0, 0, 0, then I changed my code:

- (UISearchBar *)view
{
  UISearchBar *searchBar = [[UISearchBar alloc] init];

  UIView *subUIView = searchBar.subviews.firstObject;
  CGRect screenRect = [[UIScreen mainScreen] bounds];
  [subUIView setFrame:CGRectMake(0, 0, screenRect.size.width, searchBar.intrinsicContentSize.height)];
  [subUIView.subviews.firstObject setFrame:CGRectMake(0, 0, screenRect.size.width, searchBar.intrinsicContentSize.height)];

  return searchBar;
}

The issue resolved.

@brentvatne Maybe it's a bug of react-native?

@umhan35
Copy link
Contributor

umhan35 commented Jun 13, 2015

It's not a bug. I've been using the solution I provided in my project.

Here are the obj-c and JS files. Check out the last method in RCTSearchBarManager.m. I thought I will open source this, but there are a lot of features provided by a search bar and I only use part of them.

RCTSearchBar.h

#import <UIKit/UIKit.h>

@class RCTEventDispatcher;

@interface RCTSearchBar : UISearchBar

- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher NS_DESIGNATED_INITIALIZER;

@end

RCTSearchBar.m

#import "RCTSearchBar.h"

#import "UIView+React.h"
#import "RCTEventDispatcher.h"

@interface RCTSearchBar() <UISearchBarDelegate>

@end

@implementation RCTSearchBar
{
  RCTEventDispatcher *_eventDispatcher;
}

- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
{
  if ((self = [super initWithFrame:CGRectMake(0, 0, 1000, 44)])) {
    _eventDispatcher = eventDispatcher;
    self.delegate = self;
  }
  return self;
}


- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
  [self setShowsCancelButton:YES animated:YES];

  [_eventDispatcher sendTextEventWithType:RCTTextEventTypeFocus
                                 reactTag:self.reactTag
                                     text:searchBar.text];
}

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
  [_eventDispatcher sendTextEventWithType:RCTTextEventTypeChange
                                 reactTag:self.reactTag
                                     text:searchText];
}

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
  NSDictionary *event = @{
                          @"target": self.reactTag,
                          @"button": @"search",
                          @"searchText": searchBar.text
                          };

  [_eventDispatcher sendInputEventWithName:@"topTap" body:event];
}


- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
  self.text = @"";
  [self resignFirstResponder];
  [self setShowsCancelButton:NO animated:YES];

  NSDictionary *event = @{
                          @"target": self.reactTag,
                          @"button": @"cancel"
                          };

  [_eventDispatcher sendInputEventWithName:@"topTap" body:event];
}


@end

RCTSearchBarManager.h

#import "RCTViewManager.h"

@interface RCTSearchBarManager : RCTViewManager

@end

RCTSearchBarManager.m

#import "RCTSearchBarManager.h"

#import "RCTSearchBar.h"

#import "RCTBridge.h"

@implementation RCTSearchBarManager

RCT_EXPORT_MODULE()

- (UIView *)view
{
//  RCTSearchBar *searchBar = [[RCTSearchBar alloc] initWithFrame:CGRectMake(0, 0, 1000, 44)];

  RCTSearchBar *searchBar = [[RCTSearchBar alloc] initWithEventDispatcher:self.bridge.eventDispatcher];
//  RCTSearchBar *searchBar = [[RCTSearchBar alloc] init];
//[[  UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:(UIViewController *)]

  return searchBar;
}

RCT_EXPORT_VIEW_PROPERTY(placeholder, NSString)
RCT_EXPORT_VIEW_PROPERTY(showsCancelButton, BOOL)

- (NSDictionary *)constantsToExport
{
  return @{
           @"ComponentHeight": @([self view].intrinsicContentSize.height),
           };
}

@end

search_bar.js

var NativeModules, PropTypes, RCTSearchBar, React, SearchBar;

React = require('react-native');

RCTSearchBar = React.requireNativeComponent('RCTSearchBar', null);

PropTypes = require('ReactPropTypes');

NativeModules = require('NativeModules');

SearchBar = React.createClass({
  propTypes: {
    placeholder: PropTypes.string,
    showsCancelButton: PropTypes.bool,
    onChange: PropTypes.func,
    onChangeText: PropTypes.func,
    onFocus: PropTypes.func,
    onSearchButtonPress: PropTypes.func,
    onCancelButtonPress: PropTypes.func
  },
  _onChange: function(e) {
    var base, base1;
    if (typeof (base = this.props).onChange === "function") {
      base.onChange(e);
    }
    return typeof (base1 = this.props).onChangeText === "function" ? base1.onChangeText(e.nativeEvent.text) : void 0;
  },
  _onPress: function(e) {
    var base, base1, button;
    button = e.nativeEvent.button;
    if (button === 'search') {
      return typeof (base = this.props).onSearchButtonPress === "function" ? base.onSearchButtonPress(e.nativeEvent.searchText) : void 0;
    } else if (button === 'cancel') {
      return typeof (base1 = this.props).onCancelButtonPress === "function" ? base1.onCancelButtonPress() : void 0;
    }
  },
  render: function() {
    return <RCTSearchBar
      style={{height: NativeModules.SearchBarManager.ComponentHeight}}
      onChange={this._onChange}
      onPress={this._onPress}
      {...this.props}
    />;
  }
});

module.exports = SearchBar;

//# sourceMappingURL=search_bar.js.map

@umhan35
Copy link
Contributor

umhan35 commented Jun 14, 2015

@bolasblack I just open sourced react-native-search-bar on npm. Check it out on GitHub.

@brentvatne
Copy link
Collaborator

Nice one @umhan35!

@facebook facebook locked as resolved and limited conversation to collaborators May 29, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 22, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests

4 participants