I started to work with DropdownButton widget and I created List of cities. I want to see AlertDialog when i choose my favorite city on the list but it can't work.
Here is codes :
import 'package:flutter/material.dart';
import './func.dart';
class ChooseCity extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return ChooseCityState();
}
}
class ChooseCityState extends State<ChooseCity> {
var cities = ["Ankara", "İzmir", "İstanbul", "Edirne", "Antalya"];
String choosenCity = "Edirne";
#override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
DropdownButton<String>(
items: cities.map((String city) {
return DropdownMenuItem<String>(
child: Text(city),
value: city,
);
}).toList(),
value: choosenCity,
onChanged: (String choosen) {
setState(() {
choosenCity = choosen;});
choosen=="Antalya" ?
AlertDialog(
title:Text("ATTENTION"),
content: Text("You chose the best place!!"),
actions: [
FlatButton(child: Text("I see,I agree"),onPressed: ()=>{},)
],
)
: Text("go on");
},
),
SizedBox(
height: 60,
),
Text(
" You choosed :" + choosenCity,
textAlign: TextAlign.center,
),
],
);
}
}
View of my page :
It doesn't look like as i want. I want to see AlertDialog when i chose "Antalya" . Where is the error? Where should i put the bool function? I tried to put this bool function out of setState function but it didn't be as i want.
If you want to show alert dialog you should use 'showDialog', then in its builder use your Alert Dialog.
Like this
class ChooseCity extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return ChooseCityState();
}
}
class ChooseCityState extends State<ChooseCity> {
var cities = ["Ankara", "İzmir", "İstanbul", "Edirne", "Antalya"];
String chosenCity = "Edirne";
#override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
DropdownButton<String>(
items: cities.map((String city) {
return DropdownMenuItem<String>(
child: Text(city),
value: city,
);
}).toList(),
value: chosenCity,
onChanged: (String choosen) {
chosenCity = choosen;
showAlertDialog();
setState(() {});
},
),
SizedBox(
height: 60,
),
Text(
" You choosed :" + chosenCity,
textAlign: TextAlign.center,
),
],
);
}
showAlertDialog() {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text("ATTENTION"),
content: Text("You chose the best place!!"),
actions: [
FlatButton(
child: Text("I see,I agree"),
onPressed: () => {},
)
],
);
},
);
}
}
Related
How can I get the values of a column and paint the background color depending on the value.
I have the column: "Stock" and I need to know when the value is 0 to make the background red.
in this way I paint the first row of the header. Is it possible to implement the logic to obtain the mentioned values?
ws.eachRow((row, rowNumber) => {
row.eachCell((cell) => {
console.log(rowNumber);
if (rowNumber == 1) {
cell.fill = {
type: "pattern",
pattern: "solid",
fgColor: { argb: "2563EB" },
};
}
cell.font = {
color: { argb: "FFFFFF" },
bold: true,
};
cell.border = {
top: { style: "thin" },
left: { style: "thin" },
bottom: { style: "thin" },
right: { style: "thin" },
};
});
row.commit();
});
ws.addRows(arrProducts);
.......
Here's my code for my sign in page on Flutter. I have no errors, but it's still not showing the dropdown list, does anyone know why?
I've used the auto-complete search method.
Here's what I've done so far :
Edited the pubspec.yaml
Imported the unilist.json (which I'm using)
Created a Plain Old Dart Object to represent json structure
And finally, edited my sign in dart file.
I'm having no errors so far, so I believe I'm missing something..
Thanks,
import 'package:autocomplete_textfield/autocomplete_textfield.dart';
import 'package:flutter/material.dart';
import 'package:shop_app/components/custom_surfix_icon.dart';
import 'package:shop_app/components/default_button.dart';
import 'package:shop_app/components/form_error.dart';
import 'package:shop_app/screens/complete_profile/complete_profile_screen.dart';
import 'package:shop_app/screens/sign_up/components/unilist.dart';
import '../../../constants.dart';
import '../../../size_config.dart';
import 'dart:convert';
import 'package:flutter/services.dart';
TextEditingController controller = new TextEditingController();
class UniViewModel {
static List<UniName> uni;
static Future loadUni() async {
try {
uni = new List<UniName>();
String jsonString = await rootBundle.loadString('assets/unilist.json');
Map parsedJson = json.decode(jsonString);
var categoryJson = parsedJson['uni'] as List;
for (int i = 0; i < categoryJson.length; i++) {
uni.add(new UniName.fromJson(categoryJson[i]));
}
} catch (e) {
print(e);
}
}
}
class SignUpForm extends StatefulWidget {
#override
_SignUpFormState createState() => _SignUpFormState();
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: AutoComplete(),
),
);
}
}
class AutoComplete extends StatefulWidget {
#override
_AutoCompleteState createState() => new _AutoCompleteState();
}
class _AutoCompleteState extends State<AutoComplete> {
GlobalKey<AutoCompleteTextFieldState<UniName>> key = new GlobalKey();
AutoCompleteTextField searchTextField;
TextEditingController controller = new TextEditingController();
_AutoCompleteState();
void _loadData() async {
await UniViewModel.loadUni();
}
#override
void initState() {
_loadData();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: false,
appBar: AppBar(
title: Text('Auto Complete List Demo'),
),
body: new Center(
child: new Column(children: <Widget>[
new Column(children: <Widget>[
searchTextField = AutoCompleteTextField<UniName>(
style: new TextStyle(color: Colors.black, fontSize: 16.0),
decoration: new InputDecoration(
suffixIcon: Container(
width: 85.0,
height: 60.0,
),
contentPadding: EdgeInsets.fromLTRB(10.0, 30.0, 10.0, 20.0),
filled: true,
hintText: 'Search Uni Name',
hintStyle: TextStyle(color: Colors.black)),
itemSubmitted: (item) {
setState(() => searchTextField.textField.controller.text =
item.nom_court);
},
clearOnSubmit: false,
key: key,
suggestions: UniViewModel.uni,
itemBuilder: (context, item) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(item.nom_court,
style: TextStyle(
fontSize: 16.0
),),
Padding(
padding: EdgeInsets.all(15.0),
),
Text(item.localisation,
)
],
);
},
itemSorter: (a, b) {
return a.nom_court.compareTo(b.nom_court);
},
itemFilter: (item, query) {
return item.nom_court
.toLowerCase()
.startsWith(query.toLowerCase());
}),
]),
])));
}
}
class _SignUpFormState extends State<SignUpForm> {
final _formKey = GlobalKey<FormState>();
String email;
String password;
String uni;
String conform_password;
bool remember = false;
final List<String> errors = [];
void addError({String error}) {
if (!errors.contains(error))
setState(() {
errors.add(error);
});
}
void removeError({String error}) {
if (errors.contains(error))
setState(() {
errors.remove(error);
});
}
#override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Column(
children: [
buildEmailFormField(),
SizedBox(height: getProportionateScreenHeight(30)),
FormError(errors: errors),
SizedBox(height: getProportionateScreenHeight(40)),
DefaultButton(
text: "Continuer",
press: () {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
// if all are valid then go to success screen
Navigator.pushNamed(context, CompleteProfileScreen.routeName);
}
},
),
],
),
);
}
TextFormField buildConformPassFormField() {
return TextFormField(
obscureText: true,
onSaved: (newValue) => conform_password = newValue,
onChanged: (value) {
if (value.isNotEmpty) {
removeError(error: kPassNullError);
} else if (value.isNotEmpty && password == conform_password) {
removeError(error: kMatchPassError);
}
conform_password = value;
},
validator: (value) {
if (value.isEmpty) {
addError(error: kPassNullError);
return "";
} else if ((password != value)) {
addError(error: kMatchPassError);
return "";
}
return null;
},
decoration: InputDecoration(
labelText: "Confirmez le mot de passe",
hintText: "Reconfirmez le mot de passe",
// If you are using latest version of flutter then lable text and hint text shown like this
// if you r using flutter less then 1.20.* then maybe this is not working properly
floatingLabelBehavior: FloatingLabelBehavior.always,
suffixIcon: CustomSurffixIcon(svgIcon: "assets/icons/Lock.svg"),
),
);
}
TextFormField buildPasswordFormField() {
return TextFormField(
obscureText: true,
onSaved: (newValue) => password = newValue,
onChanged: (value) {
if (value.isNotEmpty) {
removeError(error: kPassNullError);
} else if (value.length >= 8) {
removeError(error: kShortPassError);
}
password = value;
},
validator: (value) {
if (value.isEmpty) {
addError(error: kPassNullError);
return "";
} else if (value.length < 8) {
addError(error: kShortPassError);
return "";
}
return null;
},
decoration: InputDecoration(
labelText: "Mot de passe",
hintText: "Saisissez votre mot de passe",
// If you are using latest version of flutter then lable text and hint text shown like this
// if you r using flutter less then 1.20.* then maybe this is not working properly
floatingLabelBehavior: FloatingLabelBehavior.always,
suffixIcon: CustomSurffixIcon(svgIcon: "assets/icons/Lock.svg"),
),
);
}
TextFormField buildEmailFormField() {
return TextFormField(
keyboardType: TextInputType.emailAddress,
onSaved: (newValue) => email = newValue,
onChanged: (value) {
if (value.isNotEmpty) {
removeError(error: kEmailNullError);
} else if (emailValidatorRegExp.hasMatch(value)) {
removeError(error: kInvalidEmailError);
}
return null;
},
validator: (value) {
if (value.isEmpty) {
addError(error: kEmailNullError);
return "";
} else if (!emailValidatorRegExp.hasMatch(value)) {
addError(error: kInvalidEmailError);
return "";
}
return null;
},
decoration: InputDecoration(
labelText: "Email",
hintText: "Enter your email",
// If you are using latest version of flutter then lable text and hint text shown like this
// if you r using flutter less then 1.20.* then maybe this is not working properly
floatingLabelBehavior: FloatingLabelBehavior.always,
suffixIcon: CustomSurffixIcon(svgIcon: "assets/icons/Mail.svg"),
),
);
}
TextFormField buildUniFormField() {
return TextFormField(
keyboardType: TextInputType.uni,
onSaved: (newValue) => uni = newValue,
onChanged: (value) {
if (value.isNotEmpty) {
removeError(error: kEmailNullError);
} else if (emailValidatorRegExp.hasMatch(value)) {
removeError(error: kInvalidEmailError);
}
return null;
},
validator: (value) {
if (value.isEmpty) {
addError(error: kEmailNullError);
return "";
} else if (!emailValidatorRegExp.hasMatch(value)) {
addError(error: kInvalidEmailError);
return "";
}
return null;
},
);
}
}
Hello Everyone i'm a beginner. I am facing a problem. Below is my code. I want to set Future String as initial value of TextFormField. I successfully did it for only one TextFormField but now i have multiple TextFormField and i tried to fetch data from every field of firebase document and set as initial value of corresponding TextFormField.
If i assign the value to TextFormField 'label' it shows correctly but when i assign the same value to 'initial value' it doesnot show.
Sorry for poor conversation
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:shop_app/components/custom_surfix_icon.dart';
import 'package:shop_app/components/default_button.dart';
import 'package:shop_app/components/form_error.dart';
import 'package:shop_app/size_config.dart';
import '../../../../../../constants.dart';
class EditProfileForm extends StatefulWidget {
#override
_EditProfileFormState createState() => _EditProfileFormState();
}
class _EditProfileFormState extends State<EditProfileForm> {
final _formKey = GlobalKey<FormState>();
final List<String> errors = [];
String name;
String phoneNo;
String gender;
String address;
String about;
String education;
String specialities;
String languages;
String work;
String storeName;
String storePhoneNo;
String storeGender;
String storeAddress;
String storeAbout;
String storeEducation;
String storeSpecialities;
String storeLanguages;
String storeWork;
static const menuItems = <String>[
'Male',
'Female',
'Other',
];
final List<DropdownMenuItem<String>> popUpMenuItem = menuItems
.map((String value) => DropdownMenuItem<String>(
value: value,
child: Text(value),
))
.toList();
void addError({String error}) {
if (!errors.contains(error))
setState(() {
errors.add(error);
});
}
void removeError({String error}) {
if (errors.contains(error))
setState(() {
errors.remove(error);
});
}
// #override
// void initState() {
// super.initState();
// getData();
// }
getData() {
getName();
getPhoneNo();
getAddress();
getAbout();
getEducation();
getSpecialities();
getLanguages();
getWork();
}
#override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Column(
children: [
getNameFormField(),
SizedBox(height: getProportionateScreenHeight(30)),
getGenderFormField(),
SizedBox(height: getProportionateScreenHeight(30)),
getPhoneNoFormField(),
SizedBox(height: getProportionateScreenHeight(30)),
getAddressFormField(),
SizedBox(height: getProportionateScreenHeight(30)),
getAboutFormField(),
SizedBox(height: getProportionateScreenHeight(30)),
getEducationFormField(),
SizedBox(height: getProportionateScreenHeight(30)),
getSpecialitiesFormField(),
SizedBox(height: getProportionateScreenHeight(30)),
getLanguagesFormField(),
SizedBox(height: getProportionateScreenHeight(30)),
getWorkFormField(),
FormError(errors: errors),
SizedBox(height: getProportionateScreenHeight(40)),
DefaultButton(
text: "Update Profile",
press: () async {
if (_formKey.currentState.validate()) {
print(storeName);
}
},
),
],
),
);
}
///////////////////////////////////////////////////////////////////////////////
Widget getNameFormField() {
return FutureBuilder(
future: getName(),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
storeName = snapshot.data;
return TextFormField(
initialValue: storeName,
onSaved: (newValue) => name = newValue,
onChanged: (value) {
if (value.isNotEmpty) {
removeError(error: kNamelNullError);
}
name = value;
},
validator: (value) {
if (value.isEmpty) {
addError(error: kNamelNullError);
return "";
}
return null;
},
decoration: InputDecoration(
labelText: storeName,
hintText: "Enter your name",
floatingLabelBehavior: FloatingLabelBehavior.always,
suffixIcon: CustomSurffixIcon(svgIcon: "assets/icons/User.svg"),
),
);
},
);
}
Future<String> getName() async {
DocumentSnapshot document = await FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.email)
.get();
String getName = document['Name'];
return getName;
}
///////////////////////////////////////////////////////////////////////////////
Widget getPhoneNoFormField() {
return FutureBuilder(
future: getPhoneNo(),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot1) {
storePhoneNo = snapshot1.data;
return TextFormField(
initialValue: storePhoneNo,
onSaved: (newValue) => phoneNo = newValue,
onChanged: (value) {
if (value.isNotEmpty) {
removeError(error: kPhoneNumberNullError);
}
phoneNo = value;
},
validator: (value) {
if (value.isEmpty) {
addError(error: kPhoneNumberNullError);
return "";
}
return null;
},
decoration: InputDecoration(
labelText: "Phone No",
hintText: "Enter Phone No",
floatingLabelBehavior: FloatingLabelBehavior.always,
suffixIcon: CustomSurffixIcon(svgIcon: "assets/icons/Phone.svg"),
),
);
},
);
}
Future<String> getPhoneNo() async {
DocumentSnapshot document = await FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.email)
.get();
String getPhoneNo = document['Phone Number'];
return getPhoneNo;
}
///////////////////////////////////////////////////////////////////////////////
DropdownButtonFormField getGenderFormField() {
return DropdownButtonFormField(
onSaved: (newValue) {
gender = newValue;
},
onChanged: (value) {
if (value.isNotEmpty) {
removeError(error: kNamelNullError);
}
gender = value;
print(gender);
},
validator: (value) {
if (value.isEmpty) {
addError(error: kNamelNullError);
return "";
}
return null;
},
decoration: InputDecoration(
labelText: "Gender",
hintText: "Select your gender",
floatingLabelBehavior: FloatingLabelBehavior.always,
suffixIcon: CustomSurffixIcon(svgIcon: "assets/icons/gender.svg"),
),
items: popUpMenuItem,
);
}
Future<String> getGender() async {
DocumentSnapshot document = await FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.email)
.get();
String getGender = document['Gender'];
return getGender;
}
///////////////////////////////////////////////////////////////////////////////
Widget getAddressFormField() {
return FutureBuilder(
future: getAddress(),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot2) {
storeAddress = snapshot2.data;
return TextFormField(
initialValue: storeAddress,
onSaved: (newValue) => address = newValue,
onChanged: (value) {
if (value.isNotEmpty) {
removeError(error: kAddressNullError);
}
address = value;
},
validator: (value) {
if (value.isEmpty) {
addError(error: kAddressNullError);
return "";
}
return null;
},
decoration: InputDecoration(
labelText: "Address",
hintText: "Enter your address",
floatingLabelBehavior: FloatingLabelBehavior.always,
suffixIcon: CustomSurffixIcon(svgIcon: "assets/icons/Location point.svg"),
),
);
},
);
}
Future<String> getAddress() async {
DocumentSnapshot document = await FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.email)
.get();
String getName = document['Address'];
return getName;
}
///////////////////////////////////////////////////////////////////////////////
Widget getAboutFormField() {
return FutureBuilder(
future: getAbout(),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot3) {
storeAbout = snapshot3.data;
return TextFormField(
initialValue: storeAbout,
onSaved: (newValue) => about = newValue,
onChanged: (value) {
if (value.isNotEmpty) {
removeError(error: kAboutNullError);
}
about = value;
},
validator: (value) {
if (value.isEmpty) {
addError(error: kAboutNullError);
return "";
}
return null;
},
decoration: InputDecoration(
labelText: "About",
hintText: "Describe Yourself",
floatingLabelBehavior: FloatingLabelBehavior.always,
suffixIcon: CustomSurffixIcon(svgIcon: "assets/icons/User.svg"),
),
);
},
);
}
Future<String> getAbout() async {
DocumentSnapshot document = await FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.email)
.get();
String getAbout = document['About'];
return getAbout;
}
///////////////////////////////////////////////////////////////////////////////
Widget getEducationFormField() {
return FutureBuilder(
future: getEducation(),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot4) {
storeEducation = snapshot4.data;
return TextFormField(
initialValue: storeEducation,
onSaved: (newValue) => education = newValue,
onChanged: (value) {
if (value.isNotEmpty) {
removeError(error: kEducationNullError);
}
education = value;
},
validator: (value) {
if (value.isEmpty) {
addError(error: kEducationNullError);
return "";
}
return null;
},
decoration: InputDecoration(
labelText: "Education",
hintText: "Enter your education",
floatingLabelBehavior: FloatingLabelBehavior.always,
suffixIcon: CustomSurffixIcon(svgIcon: "assets/icons/User.svg"),
),
);
},
);
}
Future<String> getEducation() async {
DocumentSnapshot document = await FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.email)
.get();
String getEducation = document['Education'];
return getEducation;
}
///////////////////////////////////////////////////////////////////////////////
Widget getSpecialitiesFormField() {
return FutureBuilder(
future: getSpecialities(),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot5) {
storeSpecialities = snapshot5.data;
return TextFormField(
initialValue: storeSpecialities,
onSaved: (newValue) => specialities = newValue,
onChanged: (value) {
if (value.isNotEmpty) {
removeError(error: kSkillsNullError);
}
specialities = value;
},
validator: (value) {
if (value.isEmpty) {
addError(error: kSkillsNullError);
return "";
}
return null;
},
decoration: InputDecoration(
labelText: "Specialities",
hintText: "Enter your specialities",
floatingLabelBehavior: FloatingLabelBehavior.always,
suffixIcon: CustomSurffixIcon(svgIcon: "assets/icons/User.svg"),
),
);
},
);
}
Future<String> getSpecialities() async {
DocumentSnapshot document = await FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.email)
.get();
String getSpecialities = document['Specialities'];
return getSpecialities;
}
///////////////////////////////////////////////////////////////////////////////
Widget getLanguagesFormField() {
return FutureBuilder(
future: getLanguages(),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot6) {
storeLanguages = snapshot6.data;
return TextFormField(
initialValue: storeLanguages,
onSaved: (newValue) => languages = newValue,
onChanged: (value) {
if (value.isNotEmpty) {
removeError(error: kLanguagesNullError);
}
languages = value;
},
validator: (value) {
if (value.isEmpty) {
addError(error: kLanguagesNullError);
return "";
}
return null;
},
decoration: InputDecoration(
labelText: "Languages",
hintText: "Enter Your Languages",
floatingLabelBehavior: FloatingLabelBehavior.always,
suffixIcon: CustomSurffixIcon(svgIcon: "assets/icons/User.svg"),
),
);
},
);
}
Future<String> getLanguages() async {
DocumentSnapshot document = await FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.email)
.get();
String getLanguages = document['Languages'];
return getLanguages;
}
///////////////////////////////////////////////////////////////////////////////
Widget getWorkFormField() {
return FutureBuilder(
future: getWork(),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot7) {
storeWork = snapshot7.data;
return TextFormField(
initialValue: storeWork,
onSaved: (newValue) => work = newValue,
onChanged: (value) {
if (value.isNotEmpty) {
removeError(error: kWorkNullError);
}
work= value;
},
validator: (value) {
if (value.isEmpty) {
addError(error: kWorkNullError);
return "";
}
return null;
},
decoration: InputDecoration(
labelText: "Work",
hintText: "What you do?",
floatingLabelBehavior: FloatingLabelBehavior.always,
suffixIcon: CustomSurffixIcon(svgIcon: "assets/icons/User.svg"),
),
);
},
);
}
Future<String> getWork() async {
DocumentSnapshot document = await FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.email)
.get();
String getWork = document['Work'];
return getWork;
}
}
you can just call the function that returns you the Future String in the initState() and after that, you can set that string as TextInput hint
I'm new to programming and SwiftUI and I am making this app where users can select these buttons labeled A-D. They may choose more than 1, and I am hoping that when they click on the button, the background colour will change from grey to green. However, if I replace "// Here" in the code at the bottom with
Data.Selected = true
Data.Colour = .green
I get an error saying "Cannot assign to property: 'Data' is a 'let' constant". I understand what that means, but I don't know how to change Data to var. I tried typing var in front of "Data in" but I got this error instead "Consecutive statements on a line must be separated by ';'". Is there anyway I can directly modify Data/ButtonsData? Or is there a workaround?
struct Buttons: Hashable {
var Crit: String
var Selected: Bool
var Colour: Color
}
var ButtonsData = [
Buttons(Crit: "A", Selected: false, Colour: Color(.systemGray4)),
Buttons(Crit: "B", Selected: false, Colour: Color(.systemGray4)),
Buttons(Crit: "C", Selected: false, Colour: Color(.systemGray4)),
Buttons(Crit: "D", Selected: false, Colour: Color(.systemGray4))
]
struct CritView: View {
#Binding var CritBoard: Bool
#Binding var BackgroundColor: Color
var body: some View {
ZStack(alignment: .topLeading) {
ScrollView(.vertical, showsIndicators: false) {
HStack(spacing: 15) {
ForEach(ButtonsData, id: \.self) { Data in
Button(action: {
// HERE
}) {
Text(Data.Crit)
.font(.system(size: 30))
}
.frame(width: 65, height: 55)
.background(Data.Colour)
.cornerRadius(10)
}
}
.padding(.top, 50)
}
.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height/8)
.padding(.bottom, UIApplication.shared.windows.first?.safeAreaInsets.bottom)
.background(Color(.white))
.cornerRadius(25)
Button(action: {
self.CritBoard.toggle()
self.BackgroundColor = .white
}) {
Image(systemName: "xmark").foregroundColor(.black)
}.padding(25)
}
}
}
Here is possible solution - create array of index/value tuples and modify your data in original container by index:
ForEach(Array(ButtonsData.enumerated()), id: \.element) { i, Data in
Button(action: {
ButtonsData[i].Selected = true
ButtonsData[i].Colour = .green
}) {
Text(Data.Crit)
.font(.system(size: 30))
}
.frame(width: 65, height: 55)
.background(Data.Colour)
.cornerRadius(10)
}
Well, I don't think a lot of people would actually have the same/similar problem but this is my working code. The code uses both #Aspersi's answer as well as the code in a Hacking with Swift article. (it might not be the most simplified code, but it works right now at least)
ForEach(Array(ButtonsData.enumerated()), id: \.element) { i, Data in
Button(action: {
self.AllData[i].Selected.toggle()
if self.AllData[i].Selected == true {
self.AllData[i].Colour = .green
} else {
self.AllData[i].Colour = Color(.systemGray4)
}
}) {
Text(Data.Crit)
.font(.system(size: 30))
}
.frame(width: 65, height: 55)
.background(self.AllData[i].Colour)
.cornerRadius(10)
}
Full code below
struct Buttons: Hashable {
var Crit: String
var Selected: Bool = false
var Colour: Color
}
var ButtonsData = [
Buttons(Crit: "A", Selected: false, Colour: Color(.systemGray4)),
Buttons(Crit: "B", Selected: false, Colour: Color(.systemGray4)),
Buttons(Crit: "C", Selected: false, Colour: Color(.systemGray4)),
Buttons(Crit: "D", Selected: false, Colour: Color(.systemGray4))
]
struct CritView: View {
#Binding var CritBoard: Bool
#Binding var BackgroundColor: Color
#State private var AllData = ButtonsData
var body: some View {
ZStack(alignment: .topLeading) {
ScrollView(.vertical, showsIndicators: false) {
HStack(spacing: 15) {
ForEach(Array(ButtonsData.enumerated()), id: \.element) { I, Data in
Button(action: {
self.AllData[i].Selected.toggle()
if self.AllData[i].Selected == true {
self.AllData[i].Colour = .green
} else {
self.AllData[i].Colour = Color(.systemGray4)
}
}) {
Text(Data.Crit)
.font(.system(size: 30))
}
.frame(width: 65, height: 55)
.background(self.AllData[i].Colour)
.cornerRadius(10)
}
}
.padding(.top, 50)
}
.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height/8)
.padding(.bottom, UIApplication.shared.windows.first?.safeAreaInsets.bottom)
.background(Color(.white))
.cornerRadius(25)
Button(action: {
self.CritBoard.toggle()
self.BackgroundColor = .white
}) {
Image(systemName: "xmark").foregroundColor(.black)
}.padding(25)
}
}
}
Realm keeps throwing this error in a simple use case:
Cannot access realm that has been closed
My files:
RealmExample.js
import Realm from 'realm';
class Item {}
Item.schema = {
name: 'Item',
properties: {
name: 'string',
date: 'date',
id: 'string'
},
};
export default new Realm({schema: [Item]});
app.js
//My imports
export default class App extends Component<{}> {
render() {
return (
<RealmProvider realm={realm}>
<ConnectedExample />
</RealmProvider>
);
}
}
ConnectedExample.js
import React, { Component } from 'react';
import {
Text,
ScrollView,
TouchableOpacity,
View,
StyleSheet,
} from 'react-native';
import uuid from 'uuid';
import { connectRealm } from 'react-native-realm';
import ConnectedExampleItem from './ConnectedExampleItem';
const styles = StyleSheet.create({
screen: {
paddingTop: 20,
paddingHorizontal: 10,
backgroundColor: '#2a2a2a',
flex: 1,
},
add: {
height: 44,
alignItems: 'center',
justifyContent: 'center',
paddingHorizontal: 10,
backgroundColor: '#1a1a1a',
},
addText: {
color: 'white',
},
});
class ConnectedExample extends Component {
count = 0;
onPressAddItem = () => {
const { realm } = this.props;
realm.write(() => {
realm.create('Item', {
name: this.count.toString(),
date: new Date(),
id: uuid.v4(),
});
this.count++;
});
};
render() {
return (
<View style={styles.screen}>
<TouchableOpacity onPress={this.onPressAddItem} style={styles.add}>
<Text style={styles.addText}>Add Item</Text>
</TouchableOpacity>
<ScrollView>
{this.props.items.map((item) => (
<View key={item.id}>
<ConnectedExampleItem id={item.id} />
</View>
))}
</ScrollView>
</View>
);
}
}
export default connectRealm(ConnectedExample, {
schemas: ['Item'],
mapToProps(results, realm) {
return {
realm,
items: results.items.sorted('date') || [],
};
},
});
ConnectedExampleItem.js
import React, {
Component,
PropTypes,
} from 'react';
import {
StyleSheet,
TouchableOpacity,
Text,
} from 'react-native';
import { connectRealm } from 'react-native-realm';
const styles = StyleSheet.create({
item: {
height: 44,
justifyContent: 'center',
paddingHorizontal: 10,
marginTop: 10,
backgroundColor: 'cyan',
},
});
class ConnectedExampleItem extends Component {
onPressRemoveItem = (item) => {
const { realm } = this.props;
realm.write(() => {
realm.delete(item);
});
};
render() {
return (
<TouchableOpacity
onPress={() => this.onPressRemoveItem(this.props.item)}
style={styles.item}
>
<Text>{this.props.item.name}</Text>
</TouchableOpacity>
);
}
}
export default connectRealm(ConnectedExampleItem, {
schemas: ['Item'],
mapToProps(results, realm, ownProps) {
return {
realm,
item: results.items.find(item => item.id === ownProps.id),
};
},
});
The strange thing is that when running this code on my project I run into the Cannot access realm that has been closed (I haven't instantiated Realm anywhere else), however, if I run the example in the react-native-realm repo, it runs fine.
Also, the introduction example on the Realm documentation page runs fine as well.
What could be the issue?
Thank you.
PS: Running on React-native 0.51, Android device 6.0.