Using view in react native that was created in swift

This commit is contained in:
Artur Gurgul 2025-08-02 16:27:14 +02:00
parent 464d82cfd3
commit 97fb795866
7 changed files with 100 additions and 2 deletions

11
App.tsx
View file

@ -2,7 +2,15 @@ import { NewAppScreen } from '@react-native/new-app-screen'
import { useEffect, useState } from 'react'
import { StatusBar, Text, StyleSheet, useColorScheme, View } from 'react-native'
import { NativeEventEmitter, NativeModules } from 'react-native'
const { Emitter } = NativeModules;
const { Emitter } = NativeModules
import { requireNativeComponent } from 'react-native'
import type { StyleProp, ViewStyle } from 'react-native'
type CustomButtonProps = {
style?: StyleProp<ViewStyle>
}
const CustomButton = requireNativeComponent<CustomButtonProps>('CustomButton')
export default function App() {
const isDarkMode = useColorScheme() === 'dark'
@ -25,6 +33,7 @@ export default function App() {
<View style={styles.container}>
<StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
<Text>{message ?? 'Waiting for message...'}</Text>
<CustomButton style={{ width: 200, height: 200 }} />
<NewAppScreen templateFileName="App.tsx" />
</View>
);

View file

@ -0,0 +1,2 @@
#import <React/RCTViewManager.h>

View file

@ -0,0 +1,60 @@
//
// CustomButton.swift
// RNPlayground
//
// Created by Artur Gurgul on 02/08/2025.
//
import UIKit
import SwiftUI
@objc(CustomButton)
class CustomButton: UIView {
private let label: UILabel = {
let lbl = UILabel()
lbl.text = "Hello from native"
lbl.textColor = .white
lbl.translatesAutoresizingMaskIntoConstraints = false
return lbl
}()
private let button: UIButton = {
let btn = UIButton(type: .system)
btn.setTitle("Click Me", for: .normal)
btn.setTitleColor(.white, for: .normal)
btn.translatesAutoresizingMaskIntoConstraints = false
return btn
}()
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = .systemBlue
self.addSubview(label)
self.addSubview(button)
setupConstraints()
button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupConstraints() {
NSLayoutConstraint.activate([
label.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 16),
label.centerYAnchor.constraint(equalTo: self.centerYAnchor),
button.leadingAnchor.constraint(equalTo: label.trailingAnchor, constant: 12),
button.centerYAnchor.constraint(equalTo: self.centerYAnchor),
button.trailingAnchor.constraint(lessThanOrEqualTo: self.trailingAnchor, constant: -16)
])
}
@objc private func buttonTapped() {
}
}

View file

@ -0,0 +1,5 @@
#import <React/RCTViewManager.h>
@interface RCT_EXTERN_MODULE(CustomButtonManager, RCTViewManager)
@end

View file

@ -0,0 +1,20 @@
//
// ViewManager.swift
// RNPlayground
//
// Created by Artur Gurgul on 02/08/2025.
//
import Foundation
import React
@objc(CustomButtonManager)
class CustomButtonManager: RCTViewManager {
override func view() -> UIView! {
return CustomButton()
}
override static func requiresMainQueueSetup() -> Bool {
return true
}
}

View file

@ -139,7 +139,7 @@
LastUpgradeCheck = 1210;
TargetAttributes = {
13B07F861A680F5B00A75B9A = {
LastSwiftMigration = 1120;
LastSwiftMigration = 1640;
};
};
};
@ -291,6 +291,7 @@
);
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = RNPlayground;
SWIFT_OBJC_BRIDGING_HEADER = "Native/Application/RNPlayground-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
@ -318,6 +319,7 @@
);
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = RNPlayground;
SWIFT_OBJC_BRIDGING_HEADER = "Native/Application/RNPlayground-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};