LoginSignup
5
6

More than 5 years have passed since last update.

[React Native] iOSのUISegmentedControlクラスのブリッジを書いて画面に表示させてみる

Last updated at Posted at 2015-03-30

React Native に UISegmentedControl がないじゃん っていうのを見かけて。どうやって実装しているのか興味あったのでやり方を覚えた。

ソースコード直接みてるのでドキュメントちゃんと読んでないので間違ったこと書いているかもしれないことを留意。

まず Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.ios.js を掘ってJSでReactコンポーネントを作る

var SegmentedControlIOS = React.createClass({
  mixins: [NativeMethodsMixin],

  propTypes: {
    tintColor: PropTypes.string,
  },

  getDefaultProps: function(): DefaultProps {
    return {
      tintColor: "#007AFF",
    };
  },

  render: function() {
    return (
      <View
        style={[{height: 29, width: 140}, this.props.style]}>
        <UISegmentedControl style={[{height: 29, width: 140}]} />
      </View>
    );
  }
});

Viewでラップする。試したいだけだからheight,widthはとりあえずハードコードしちゃう。

var UISegmentedControl = createReactIOSNativeComponentClass({
  validAttributes: {},
  uiViewClassName: 'UISegmentedControl',
});

createReactIOSNativeComponentClass で呼び出したいクラスを書く。

Libraries/react-native/react-native.js の中に追加する

   PickerIOS: require('PickerIOS'),
   Navigator: require('Navigator'),
   ScrollView: require('ScrollView'),
+  SegmentedControlIOS: require('SegmentedControlIOS'),
   SliderIOS: require('SliderIOS'),
   SwitchIOS: require('SwitchIOS'),
   TabBarIOS: require('TabBarIOS'),

React/Views/RCTUISegmentedControlManager.m で呼び出される側のObjective-Cのクラスを書く。

@interface RCTUISegmentedControlManager : RCTViewManager

RCTViewManagerを継承したクラスがそのViewの管理をする。

- (UIView *)view
{
  UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:@[@"WIP1", @"WIP2", @"WIP3"]];
  [segmentedControl addTarget:self action:@selector(onChange:) forControlEvents:UIControlEventValueChanged];
  return segmentedControl;
}

-view が目的のViewを初期化返す。上記は仮のコード。
これは UISegmentedControl を直接使っているけど、React Native 用の処理を加えたかったら継承して RCTSegmentedControl のような名前のクラスをつくるのが作法のようだ。

- (void)onChange:(UISegmentedControl *)sender
{
    [self.bridge.eventDispatcher sendInputEventWithName:@"topChange" body:@{
      @"target": sender.reactTag,
      @"value": @(sender.selectedSegmentIndex)
    }];
}

onChange: ではJavaScript側に送信する処理を書く。上記はとくに何もやってない仮のコード。

RCT_EXPORT_VIEW_PROPERTY(tintColor, UIColor);
RCT_EXPORT_VIEW_PROPERTY(momentary, BOOL);

クラスのプロパティをRCT_EXPORT_VIEW_PROPERTYで公開して、JSXから設定できるようにする(ここも仮)。

そうすると

return (<SegmentedControlIOS />);

でとりあえず描画できるようになった。

スクリーンショット 2015-03-30 2.58.12 PM.png

5
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6