这是我的代码页,称为ProfileInfo:
import React from "react";
import { View, Text, StyleSheet, ActivityIndicator } from "react-native";
import {
widthPercentageToDP as wp,
heightPercentageToDP as hp,
} from "react-native-responsive-screen";
import RegisterTextBox from "../../components/RegisterTextBox";
import AuthButton from "../../components/AuthButton";
import Avatar from "../../components/Avatar";
import firebase from "../../util/firebase";
import { setPhone, setIsProfileFilled } from "../../util/database";
export default class PersonalInfo extends React.Component {
constructor(props) {
super(props);
this.updateUser = this.updateUser.bind(this);
this.state = {
displayName: "",
phoneNumber: "",
photoURL: "",
buttonColor: "#8b898a",
isLoading: false,
};
}
updateInputVal = (val, prop) => {
this.setState({ [prop]: val });
this.changeColor();
};
changeColor() {
let currentColor = this.state.buttonColor;
if (this.state.displayName != "" && this.state.phoneNumber != "") {
currentColor = "#7356bf";
} else currentColor = "#8b898a";
this.setState({ buttonColor: currentColor });
}
updateUser() {
this.setState({ isLoading: true });
var user = firebase.auth().currentUser;
user
.updateProfile({
displayName: this.state.displayName,
photoURL: this.state.photoURL,
phoneNumber: setPhone(user.uid, this.state.phoneNumber),
})
.then(function () {
// Update successful.
console.log("Update Succed Moving to Update User Is Filled");
})
.then(() => {
user.updateProfile({
displayName: setIsProfileFilled(user.uid, true),
});
console.log("Update Succed Is Filled");
this.setState({ isLoading: false });
})
.catch(function (error) {
// An error happened.
console.log(error);
this.setState({ isLoading: false });
});
this.props.navigation.navigate("Waiting");
}
render() {
const { navigation } = this.props;
return (
<View style={styles.container}>
<View style={styles.titleContainer}>
<Text style={styles.title}>Great! Let’s get to know YOU</Text>
</View>
<View style={styles.imageContainer}>
<Avatar />
</View>
<View style={styles.inputContainer}>
<RegisterTextBox
type="name"
style={styles.emailInput}
placeholder="Your Name"
value={this.state.displayName}
onChangeText={(name) => {
this.updateInputVal(name, "displayName");
}}
/>
<RegisterTextBox
type="number"
style={styles.emailInput}
placeholder="Phone Number"
value={this.state.phoneNumber}
onChangeText={(number) =>
this.updateInputVal(number, "phoneNumber")
}
/>
</View>
<View style={styles.buttonContainer}>
<AuthButton
style={{ backgroundColor: this.state.buttonColor }}
// CR: Use Disabled property instead of changing the style
// disabled
title="Continue"
onPress={this.updateUser}
text="Continue"
></AuthButton>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
//Containers
container: {
flex: 1,
},
titleContainer: {
height: hp(10),
width: wp(65.7),
alignItems: "center",
marginLeft: wp(17.4),
marginRight: wp(17.4),
marginTop: hp(12.7),
},
inputContainer: {
marginTop: hp(6),
width: wp(65.2),
alignItems: "center",
marginLeft: wp(17.4),
marginRight: wp(17.4),
},
imageContainer: {
marginTop: hp(7.3),
alignItems: "center",
height: hp(14.4),
width: wp(100),
},
buttonContainer: {
marginTop: hp(9),
marginBottom: hp(14.1),
alignItems: "center",
},
//Button
loginButton: {
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
borderRadius: 32.5,
width: wp(78.3),
height: hp(7.3),
backgroundColor: "grey",
},
//Text
title: {
flex: 1,
textAlign: "center",
fontSize: hp(3.8),
},
});
这是我的导航器:
import React from "react";
import { createStackNavigator } from "@react-navigation/stack";
//Screens
import Splash from "../screens/Auth/Splash";
import Login from "../screens/Auth/Login";
import Register from "../screens/Auth/Register";
import PersonalInfo from "../screens/Auth/PersonalInfo";
import Waiting from "../screens/Waiting";
const Stack = createStackNavigator();
export const AuthStack = () => {
return (
<Stack.Navigator initialRouteName="Splash">
<Stack.Screen
name="Splash"
component={Splash}
options={{ headerShown: false, headerTransparent: true }}
/>
<Stack.Screen name="Login" component={Login} />
<Stack.Screen
name="Register"
component={Register}
options={{ headerTransparent: true, headerTitle: "" }}
/>
<Stack.Screen
name="PersonalInfo"
component={PersonalInfo}
options={{ headerTitle: "", headerTransparent: true }}
/>
<Stack.Screen
name="Waiting"
component={Waiting}
options={{ headerTitle: "", headerTransparent: true }}
/>
</Stack.Navigator>
);
};
我不明白为什么导航是未定义的,我正在尝试在updateuser
完成后进行导航。
我也尝试navigation.navigate("Waiting");
还是没有运气,
我不知道为什么无法识别我的导航器,其他页面只能在我遇到问题的页面上正常工作,也许我的功能有问题?
答案 0 :(得分:2)
我创建了一个无需道具即可从任何地方导航的类。如果您愿意,可以使用我的课程。首先,您必须设置顶级导航。
在我的NavigationService.js中
import UIKit
import Foundation
import SwipeCellKit
import CoreData
//MARK: - Protocol to transfer the task Label to main VC:
protocol TaskDelegate {
func updateTaskName(name:String)
}
//MARK: - Tasks View Controller:
class TasksViewController: UITableViewController, SwipeTableViewCellDelegate {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
var tasksArray = [Task]()
var delegate: TaskDelegate?
var taskName = ""
override func viewDidLoad(){
super.viewDidLoad()
loadTasks()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.navigationBar.prefersLargeTitles = true
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
navigationController?.navigationBar.prefersLargeTitles = false
}
// MARK: - Table view data source
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return tasksArray.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "taskCell") as! SwipeTableViewCell
cell.delegate = self
cell.textLabel?.text = tasksArray[indexPath.row].title
cell.imageView?.image = UIImage(named: "icon-unchecked-checkbox.png")
cell.detailTextLabel?.text = ""
return cell
}
// MARK: - Table view delegate methods:
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> [SwipeAction]? {
guard orientation == .right else { return nil }
let deleteAction = SwipeAction(style: .destructive , title: .none) { action, indexPath in
// handle action by updating model with deletion
self.context.delete(self.tasksArray[indexPath.row])
self.tasksArray.remove(at: indexPath.row)
self.delegate?.updateTaskName(name: "")
self.saveTasks()
}
let infoAction = SwipeAction(style: .default, title: .none) { action, indexPath in return }
deleteAction.transitionDelegate = ScaleTransition.default
// deleteAction.transitionDelegate = ScaleTransition.init(duration: 0.50, initialScale: 0.50, threshold: 0.50)
infoAction.transitionDelegate = ScaleTransition.default
// customize the action appearance
deleteAction.image = UIImage(named: "icon-trash")
infoAction.image = UIImage(named: "icon-more")
return [deleteAction, infoAction]
}
// method to customize the behavior of the swipe actions(the delete action):
func tableView(_ tableView: UITableView, editActionsOptionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> SwipeOptions {
var options = SwipeOptions()
options.expansionStyle = .destructive
options.transitionStyle = .drag
options.buttonSpacing = 10
options.expansionDelegate = ScaleAndAlphaExpansion.init(duration: 0.15, scale: 0.5, interButtonDelay: 0.30)
return options
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
if tableView.cellForRow(at: indexPath)?.imageView?.image == UIImage(named: "icon-checked-checkbox.png") {
let imageBox = UIImage(named: "icon-unchecked-checkbox.png")
tableView.cellForRow(at: indexPath)?.imageView?.image = imageBox
} else {
let imageBox = UIImage(named: "icon-checked-checkbox.png")
tableView.cellForRow(at: indexPath)?.imageView?.image = imageBox
}
}
// MARK: - Class Methods:
//Adding task function:
@IBAction func addPressedButton(_ sender: UIBarButtonItem) {
var textField = UITextField()
let alert = UIAlertController(title: "New Task", message: "Please insert a new task.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
alert.addTextField(configurationHandler: { alertTextField in
alertTextField.placeholder = "Please insert your task"
textField = alertTextField
})
alert.addAction(UIAlertAction(title: "OK", style: .destructive, handler: { action in
//We Add the task into our array of Task objects once we reach into here:
let newTask = Task(context: self.context)
newTask.title = textField.text
self.taskName = newTask.title!
self.delegate?.updateTaskName(name: self.taskName)
self.tasksArray.append(newTask)
self.saveTasks()
self.tableView.reloadData()
}))
self.present(alert, animated: true)
}
func getDate() -> String{
let dateFormatter : DateFormatter = DateFormatter()
// dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
dateFormatter.dateFormat = "yyyy-MMM-dd HH:mm:ss"
let date = Date()
let dateString = dateFormatter.string(from: date)
let interval = date.timeIntervalSince1970
return dateString
}
}
如何使用?
import { NavigationActions } from 'react-navigation';
class NavigationService{
_navigator = null;
currentRoute = null;
isNavigated = false;
setTopLevelNavigator(navigatorRef) {
_navigator = navigatorRef;
}
navigate(routeName, params) {
_navigator.dispatch(
NavigationActions.navigate({
type: NavigationActions.NAVIGATE,
routeName,
params,
})
);
}
setCurrentRoute(routName){
this.currentRoute = routName;
}
setNavigated(status){
this.isNavigated = status;
}
}
// add other navigation functions that you need and export them
const Navigation = new NavigationService();
export default Navigation;