Ինչպես փակել ստեղնաշարը React նավիգացիայի միջոցով React Native հավելվածներում

Ստեղնաշարերը թաքցնելն ու ցուցադրելը կարծես թե աննշան առաջարկ է բջջային հավելվածներում, բայց դժվար է դրանք թաքցնել ինքնաբերաբար, երբ օգտագործվում են React նավիգացիայի և մոդալ ներկայացման հետ համատեղ: Համենայն դեպս այդպիսին էր իմ նախնական ենթադրությունը: Այս հոդվածը մանրամասն նկարագրում է այն, ինչ ես սովորեցի ստեղնաշարի աշխատանքի մասին և ինչպես կարող եք խուսափել լրացուցիչ մուտքագրումից TextInput- ի օգտագործման ժամանակ: Բոլոր գրադարանների բաց աղբյուրի ֆունկցիոնալության շնորհիվ կլինեն նաև բազմաթիվ կոդերի հեգնումներ: React Native- ի տարբերակը, որը ես օգտագործում եմ գրելու պահին, 0.57.5 է

Ներկառուցված TextInput բաղադրիչը

React Native- ը պարունակում է մի շարք հիմնական բաղադրիչներ: Դրանցից մեկը TextInput- ն է, որը թույլ է տալիս տեքստ մուտքագրել հավելվածի մեջ ՝ օգտագործելով ստեղնաշար:

ներմուծել React, {Բաղադրիչը} '' արձագանքելից '; Ներմուծեք «AppRegistry, TextInput} - ը '' Reaction-native '- ից;
Արտահանել ստանդարտ դաս UselessTextInput ընդլայնված բաղադրիչ {կոնստրուկտոր (հենակետ) {սուպեր (հենակ); this.state = {text: 'Անօգուտ տեղապահ'}; }
մատուցել () {վերադարձ ( this.setState ({text})} արժեք = {this.state.text} />); }}

Վերջ, երբ կտտացնում ենք տեքստի գրառմանը, հայտնվում է ստեղնաշար, որի միջոցով կարող ենք արժեքներ մուտքագրել: Էկրանի ցանկացած կետ սեղմելով ՝ ստեղնաշարը թաքցնելու համար ստեղնաշարի միջոցով կարող եք օգտագործել TouchableWithoutFeedback- ը: Սա նման է UITapGestureRecognizer- ին iOS UIView- ում և զանգի տեսքում: endEditing

Ներմուծեք {Keyboard} ստանդարտ ստեղնաշարից. Արձակել ()

ScrollView- ում տեքստի մուտքագրումը

Սովորաբար, տեքստի որոշ մուտքագրում պետք է լինի ոլորման բաղադրիչ: React Native- ում սա հիմնականում ScrollView է ՝ բովանդակության երկար ցուցակը կարգավորելու և ստեղնաշարերից խուսափելու համար: Երբ TextInput- ը ScrollView- ում է, ստեղնաշարի փակման եղանակը մի փոքր այլ կերպ է վարվում և կախված է ստեղնաշարից

Նշում է, երբ մուտքագրումից հետո ստեղնաշարը պետք է տեսանելի մնա:

  • 'երբեք' (լռելյայն). Եթե ստեղնաշարի բաց ժամանակ մուտքագրում եք կենտրոնացված տեքստի մուտքագրումից դուրս, ստեղնաշարը կփակվի: Այս դեպքում երեխաներին ծորակ չեն տալու:
  • «Միշտ», ստեղնաշարը ինքնաբերաբար չի փակվում, և ոլորման տեսքը չի ճանաչում հպումը, բայց ոլորման տեսքի երեխաները կարող են հայտնաբերել հպումը:
  • 'բուժված'. Ստեղնաշարն ինքնաբերաբար չի փակվում, եթե երեխան (կամ նախնին) զբաղված էր մեքենագրությամբ:

Երբեք ռեժիմը շատ դեպքերում պետք է լինի ցանկալի վարքը: Եթե ​​կտտացնում եք տեքստի կենտրոնացված մուտքագրման սահմաններից դուրս, ստեղնաշարն անհետանում է:

Իմ հավելվածում կա տեքստի մուտքագրում և գործողության կոճակ: Սցենարն այն է, որ օգտվողները մուտքագրեն որոշ տեղեկություններ, ապա սեղմեն այս կոճակը ՝ տվյալները գրանցելու համար: Երբեք ռեժիմում մենք պետք է երկու անգամ սեղմենք ստեղնը, մեկը ստեղնաշարի թաքցնելու համար, և երկուսը `ստեղնը սեղմելու համար: Այսպիսով, լուծումը միշտ ռեժիմն օգտագործելն է: Այս եղանակով կոճակը միշտ առաջին հերթին ստանում է մամուլի իրադարձությունը:

ScrollView- ը հոգ է տանում ստեղնաշարի մասին

Հայրենի RCTScrollView դասը, որն աջակցում է բնիկ ScrollView գործառույթին, ունի լիցքաթափման ռեժիմի կոդ

RCT_SET_AND_PRESERVE_OFFSET (setKeyboardDismissMode, KeyboardDismissMode, UIScrollViewKeyboardDismissMode)

Ընտրված տարբերակը UIScrollViewKeyboardDismissMode է ստեղնաշարի DismissMode հատկության համար

Ստեղնաշարի փակման եղանակը, երբ ոլորումը սկսվում է քաշելիս:

Ինչպես տեսնում եք, հնարավոր ռեժիմները միացված են և ինտերակտիվ: Եվ արձագանքեք, բնիկն անում է դրա ճշգրտման կետը keyboardShouldPersistTaps- ի միջոցով

case none Ստեղնաշարը քարշ տալով չի ազատվում:

case onDrag Ստեղնաշարը փակվում է, երբ սկսվում է քարշման գործողությունը:

գործի ինտերակտիվ Ստեղնաշարը հետևում է էկրանին սենսորային էկրանի ձգմանը և լիցքը չեղյալ համարելու համար այն կարող է կրկին բարձրացվել:

ScrollView- ը մոդալով

Այնուամենայնիվ, սա չի գործում, երբ ScrollView- ը մոդալ է: Մոդալ ասելով `նկատի ունեմ React Native- ում մոդալ բաղադրիչը: Միակ գրադարանը, որը ես օգտագործում եմ, React նավիգացիան է: Այն նաև աջակցում է լրիվ էկրանով մոդալի բացմանը, բայց React նավիգացիայում մոդալ հայտարարելու եղանակը կարծես Stack լինի և շփոթեցնող է, ուստի ես նախընտրում եմ այն ​​չօգտագործել: React-Native- ում ես օգտագործում եմ մոդալ, և դա բավականին լավ է աշխատում:

Այսպիսով, եթե մենք ունենք ModI- ում ScrollView- ում TextInput, keyboardShouldPersistTaps- ը չի աշխատի: Մոդալաբար կարծես գիտի ծնողի ScrollView- ը, ուստի մենք պետք է հայտարարենք keyboardShouldPersistTaps = 'միշտ' յուրաքանչյուր ծնողի համար ScrollView: React Native- ում, FlatList- ը և SectionList- ն օգտագործում են ScrollView- ը կափարիչի տակ, այնպես որ մենք պետք է իմանանք ScrollView- ի այս բոլոր բաղադրիչները:

Speleology React Navigation

Քանի որ իմ հավելվածը մեծապես կախված է արձագանքման նավիգացիայից, լավ է խորը պատկերացում ունենալ դրա բաղադրիչների մասին, որպեսզի կարողանանք համոզվել, թե որտեղ է խնդիրը: Ես մի փոքր ներքև գրեցի արձագանքման նավիգացիայի կառուցվածքի մասին:

Anyանկացած ավանդական բջջային հավելվածի պես, իմ հավելվածը բաղկացած է ներդիրի նավիգատորի բազում նավիգավարներից: IOS- ում դա նշանակում է, որ UITabbarController- ում շատ UINavigationViewControllers կան: React նավիգացիայում ես օգտագործում եմ createMaterialTopTabNavigator ՝ createBottomTabNavigator- ի շրջանակներում

{createMaterialTopTabNavigator} ներմուծումը «واکنش-նավարկությունից»

Էկրանը, որի հետ ես ստեղնաշարի խնդիր ունեմ, մոդալ է, որը ցուցադրվում է խմբային նավիգատորներից մեկի երկրորդ էկրանով: Այսպիսով, եկեք ուսումնասիրենք հիերարխիայի ScrollView- ի բոլոր հնարավոր տարրերը: Այս գործընթացը ներառում է շատ կոդերի ընթերցում, ուստի ես սիրում եմ բաց կոդով:

Նախ, եկեք սկսենք createBottomTabNavigator- ից, որն օգտագործում է createTabNavigator- ը իր սեփական TabNavigationView- ի հետ միասին

TabNavigationView դասը տարածվում է React.PureComponent- ի վրա
արտահանել լռելյայն createTabNavigator (TabNavigationView);

Ներդիրի նավիգատորն ունի ScreenContainer- ի տակ գտնվող ներդիրի նշանի տեսք, որն օգտագործվում է դիտումը պարունակելու համար: ScreenContainer- ը գալիս է React-Native-Screens- ից: Հետևյալը նկարագրում է, թե ինչպես է գործում ներդիրի նավիգատորը:

մատուցել () {const {նավիգացիա, մատուցելՍցենա, ծույլ} = this.props; const {երթուղիներ} = նավիգացիա. պետություն; const {loaded} = this.state return ( {route.map ((երթուղի, ցուցիչ) => {եթե (ծույլ &&! loaded.includes (ինդեքս)) {// Մի ցուցադրեք էկրան, եթե մենք երբեք այնտեղ չենք նավարկել, վերադարձեք null; const isFocused = navigation.state.index === ինդեքսի վերադարձ {renderScene ({route})} ); })} {this._renderTabBar ()} ); }

Ներդիրների շարքը տրված է BottomTabBar- ով `_renderTabBar գործառույթով: Կոդին նայելով ՝ ներդիրների ամբողջ նավարկիչը ոչ մի կապ չունի ScrollView– ի հետ:

Այսպիսով, կասկածյալների ցուցակում կա միայն createMaterialTopTabNavigator: Ես այն օգտագործում եմ swipeEnabled- ով `հավելվածում, ճիշտ է: Եվ եթե նայեք ներմուծումներին, վերևի ներդիրի նավարկիչն ունի

ներմուծել MaterialTopTabBar, {type TabBarOptions,} '' ../views/MaterialTopTabBar '- ից;

MaterialTopTabBar- ը ներմուծում է ռեակտիվ ներդիրի տեսքից

Ներմուծեք {TabBar} - ը 'Reactive-Native-Tab-View' - ից;

որն ունի ScrollView- ը


  

KeyboardShouldPersistTaps հատկությունը սկզբում դրված էր միշտ և այնուհետև վերակայեց կարգավորելու համար, որպեսզի խուսափի այն սխալից, որ ներդիրի տողի ոչ մի կոճակ հնարավոր չէ սեղմել, մինչ ստեղնաշարը բաց էր: Https://github.com/react-native-community/react-native -tab-view / Issues / 375

Այնուամենայնիվ, այս TabBar- ը ոչ մի կապ չունի մեր խնդրի հետ, քանի որ այն պարունակում է միայն կոճակներ էջանիշի տողի համար:

Սահեցրեք createMaterialTopTabNavigator- ում

Եթե ​​մենք նորից նայենք createMaterialTopTabNavigator- ին, մենք ավելի շատ ներմուծումներ ենք տեսնում պատասխանատու ներդիրի տեսքից

Ներմուծեք {TabView, PagerPan} - ը 'Reactive-Native-Tab-View' - ից;

TabView- ն անցել է swipeEnabled- ը

Վերադառնալ ( );

և այն մատուցում է PagerDefault- ը, որն իր հերթին օգտագործում է PagerScroll- ը iOS- ի համար

Ներմուծել {Պլատֆորմը '' արձագանքել բնիկից ';
թող pager;
անջատիչ (Platform.OS) {case 'android': Pager = պահանջում ('./ PagerAndroid'): Լռելյայն; ընդմիջում; գործ «ios». Pager = պահանջում ('./ PagerScroll'): Լռելյայն; ընդմիջում; Ստանդարտ. Pager = պահանջում ('./ PagerPan'): Լռելյայն; ընդմիջում; }
Արտահանել ստանդարտ էջագրիչներ;

Այսպիսով, PagerScroll- ն օգտագործում է ScrollView- ը `ոլորումը կարգավորելու համար, որպեսզի համապատասխանի այն նյութի ոճին, որով օգտվողը կարող է ոլորել էջերի միջև, և այն ունի keyboardShouldPersistTaps =" միշտ ", որը պետք է ճիշտ լինի:

Վերադառնալ (

Այսպիսով, React նավիգացիայում ոչինչ կասկածելի չի թվում, այդ իսկ պատճառով ես շտապ պետք է նայեմ իմ նախագծի ծածկագրին:

Սխալեցրեք FlatList- ը, SectionList- ը և ScrollView- ը

Ինչպես նշվեց այս հոդվածի սկզբում, հիմնական խնդիրն այն է, որ keyboardShouldPersistTaps- ը պետք է հայտարարված լինի հիերարխիայի ScrollView բոլոր ծնողական տարրերի համար: Դա նշանակում է, որ փնտրեք FlatList, SectionList և ScrollView

Բարեբախտաբար, կան React devtools, որոնք ցույց են տալիս React հավելվածի բոլոր մատուցվող բաղադրիչների ծառը, որոնք նույնպես պահվում են React Native- ի կարգաբերման կարգի բաժնում:

React- ի բաղադրիչի հիերարխիան կարգաբերելու համար կարող եք օգտագործել React Developer Tools- ի առանձին տարբերակը: Տեղադրեք React-devtools փաթեթը ամբողջ աշխարհում `այն օգտագործելու համար.

npm տեղադրել -g պատասխան-devtools

Որոնումը կատարելուց հետո ես գտա, որ հիերարխիայում կա բաժնի ցուցակ, որը պետք է ունենա keyboardShouldPersistTaps = «միշտ», եթե չունի:

Երբ ուշադիր նայեցի ծածկագիրը, ես գտա, որ մոդալը գալիս է SectionList տարրից: Մենք արդեն գիտենք, որ արձագանքման բնիկում մոդալ հրահրելը նշանակում է, որ այս մոդալը ներդրված է տեսքի հիերարխիայում և նրա տեսանելիությունը վերահսկվում է կարգավիճակի միջոցով: Տեսանկյունից և բաղադրիչից ելնելով `մոդալը բաժնի ցուցակում է: Եվ ձեր հետաքրքրության համար, եթե դուք խորը մեջ եք մտնում ռեակտիվ բնածին կոդի մեջ, իմ դեպքում, SectionList- ը պարզապես VirtualizedSectionList է, այսինքն `VirtualizedList- ն օգտագործելով ScrollView

Այս բաժնի ցուցակում keyboardShouldPersistTaps = 'միշտ' հայտարարելուց հետո խնդիրը լուծվում է: Օգտվողն այժմ կարող է պարզապես մուտքագրել որոշ արժեքներ տեքստի մուտքագրման մեջ, ապա մեկ անգամ կտտացնել «Ներկայացնել» կոճակին ՝ տվյալներն ուղարկելու համար: Կոճակն այժմ գրառում է նախ հպման իրադարձությունները ՝ ոլորման տեսքի փոխարեն:

Որտեղ եք ուզում այստեղից գնալ:

Բարեբախտաբար, դրա լուծումը պարզ է, քանի որ մեր կոդը պետք է ֆիքսվի ՝ առանց փոխելու ռեակցիայի նավիգացիոն կոդը: Այնուամենայնիվ, լավ է կարդալ գրադարանի ծածկագիրը ՝ իմանալու համար, թե ինչ է նա անում և հետևելու, թե որտեղ է ծագում խնդիրը: Շնորհակալություն այս երկար ուսումնասիրությանը հետեւելու համար, և հուսով եմ ՝ ինչ-որ բան սովորեցիք:

Եթե ​​ձեզ դուր է գալիս այս հաղորդագրությունը, կարող եք ստուգել իմ մյուս հոդվածներն ու հավելվածները