ParagraphStyle — a szöveges bekezdés vizuális megjelenését meghatározó formázási paraméterek összessége. Mobilfejlesztésben a ParagraphStyle magában foglalja az igazítást (left, center, right, justified), sorközöket, első sor behúzását, bekezdések közötti távolságokat és a szöveg irányát. A Material Design Typography Guidelines (2025) szerint a ParagraphStyle következetes használata az alkalmazás minden képernyőjén egységes tipográfiai ritmust biztosít és csökkenti a vizuális zajt a szakaszok közötti váltáskor.
Lényeges
ParagraphStyle (bekezdésstílus) — egy vagy több szövegbekezdésre alkalmazott formázási szabályok gyűjteménye. Ellentétben a karakterstílusokkal (bold, italic, font-size), amelyek egyedi karakterek szintjén működnek, a ParagraphStyle makró tulajdonságokat kezel: a szöveg elhelyezését a tárolóban, sorok és bekezdések közötti távolságokat, írásirányt és elválasztási szabályokat.
Történelmileg a ParagraphStyle fogalma az asztali kiadói rendszerekből (QuarkXPress, PageMaker, InDesign) származik, ahol minden bekezdésnek megvolt a saját paraméterkészlete. A mobilfejlesztésben ez a megközelítés programozási API-kká alakult át: NSMutableParagraphStyle iOS-ben, ParagraphStyle és LineBreakStyle osztályok Androidban, valamint olyan paraméterek, mint a textAlign és textHeightBehavior Flutterben. Mindegyik ugyanazt a feladatot oldja meg — bekezdésformázás kezelése kódon keresztül, anélkül hogy egy adott szövegmotorhoz kötődne.
A Bringhurst — The Elements of Typographic Style (2024) szerint a ParagraphStyle helyes konfigurálása a felület tipográfiai kultúrájának alapja. Ha a betűtípus és méret a szöveg „hangjáért" felel, a bekezdésstílus annak „lélegzetéért": ritmus, szünetek és hangsúlyok. Mobil felületeken, ahol a hely korlátozott, a megfelelő ParagraphStyle lehetővé teszi több információ elhelyezését az olvashatóság elvesztése nélkül.
ParagraphStyle több tulajdonságcsoportot foglal magában, amelyek mindegyike a formázás egy adott aspektusáért felel. Tekintsük át a mobil API-kban elérhető legfontosabb paramétereket. Igazítás (alignment) — a fő paraméter, amely meghatározza a szöveg vízszintes helyzetét. iOS-ben NSTextAlignment, Androidban Layout.Alignment, Flutterben TextAlign érhető el.
| Tulajdonság | iOS (NSMutableParagraphStyle) | Android (Compose) | Flutter (TextStyle) |
|---|---|---|---|
| Igazítás | alignment | textAlign | textAlign |
| Bal behúzás | headIndent | textIndent (Compose-ban) | — |
| Jobb behúzás | tailIndent | — | — |
| Első sor behúzása | firstLineHeadIndent | textIndent (firstLine) | — |
| Bekezdések közötti távolság | paragraphSpacing | paragraphStyle (lineHeight) | — |
| Távolság bekezdés előtt | paragraphSpacingBefore | — | — |
| Szöveg iránya | baseWritingDirection | TextDirection (Compose) | textDirection |
| Sor törési mód | lineBreakMode | overflow (TextStyle) | overflow (TextStyle) |
Fontos megérteni, hogy nem minden tulajdonság érhető el minden platformon azonos mértékben. Például az első sor behúzása (firstLineHeadIndent) teljes mértékben csak iOS-ben támogatott az NSMutableParagraphStyle-on keresztül. Androidban erre a célra SpannableString-et használnak LeadingMarginSpan-nel, Flutterben pedig RichText-et egyedi TextSpan-nel és padding-gal. Platformok közötti fejlesztésben (Flutter, React Native) a ParagraphStyle egyes tulajdonságait tárolókon vagy Spacer-en keresztül kell emulálni.
iOS-ben a bekezdésstílussal való munkához az NSMutableParagraphStyle osztály a fő eszköz — az NSParagraphStyle alosztálya. Teljes tulajdonságkészletet biztosít a bekezdésformázás kezeléséhez, és az NSAttributedString-en keresztül alkalmazható. Az NSMutableParagraphStyle nem csak UILabel-ben és UITextView-ben használatos, hanem a Core Text-ben is a CTParagraphStyle-on keresztül.
// iOS: teljes ParagraphStyle konfiguráció
let paragraphStyle = NSMutableParagraphStyle()
// Igazítás
paragraphStyle.alignment = .justified // justified
// Behúzás
paragraphStyle.headIndent = 16 // bal behúzás
paragraphStyle.tailIndent = -16 // jobb behúzás (negatív)
paragraphStyle.firstLineHeadIndent = 32 // első sor behúzása
// Bekezdésköz
paragraphStyle.paragraphSpacing = 12 // bekezdés után
paragraphStyle.paragraphSpacingBefore = 8 // bekezdés előtt
// Sormagasság
paragraphStyle.minimumLineHeight = 24
paragraphStyle.maximumLineHeight = 24
let attributes: [NSAttributedString.Key: Any] = [
.font: UIFont.systemFont(ofSize: 16),
.paragraphStyle: paragraphStyle
]
let label = UILabel()
label.attributedText = NSAttributedString(
string: "This paragraph has a custom ParagraphStyle.\n\nSecond paragraph with 12 pt spacing.",
attributes: attributes
)
SwiftUI-ban nincs az NSMutableParagraphStyle-nak közvetlen megfelelője — helyette módosítók kombinációját használják: .multilineTextAlignment() igazításhoz, .lineSpacing() sorközhöz. Az első sor behúzásához és bekezdések közötti távolságokhoz SwiftUI-ban Text + padding vagy AttributedString (iOS 15+-tól elérhető) használandó.
// SwiftUI: AttributedString ParagraphStyle-lal (iOS 15+)
var attributed: AttributedString = """
This is the first paragraph with indent.
This is the second paragraph with 12 pt spacing.
"""
let ps = NSMutableParagraphStyle()
ps.paragraphSpacing = 12
ps.firstLineHeadIndent = 20
let container = AttributeContainer()
.paragraphStyle(ps)
attributed.mergeAttributes(container)
Text(attributed)
.font(.body)
Az Apple — Text Programming Guide (2025) szerint az NSMutableParagraphStyle akár 14 különböző formázási paramétert támogat. Fontos megjegyezni, hogy a tailIndent negatív értékkel van beállítva a tároló szélességéhez képest, a headIndent pedig pozitívként. Ez a nem nyilvánvaló viselkedés gyakran vezet hibákhoz a kezdő iOS-fejlesztőknél.
Android-ban a ParagraphStyle megközelítése eltér a View-rendszer és a Jetpack Compose között. A klasszikus View-rendszerben a bekezdésparaméterek a TextView XML attribútumain (android:textAlignment, android:lineSpacingExtra) vagy a SpannableString-en keresztül állíthatók be az android.text.style csomag ParagraphStyle interfészének implementációival.
// Android View rendszer: ParagraphStyle SpannableString-en keresztül
val text = "First paragraph with settings.\n\nSecond paragraph."
val spannable = SpannableString(text)
// Sorkizárt igazítás
spannable.setSpan(
AlignmentSpan.Standard(Layout.Alignment.ALIGN_NORMAL),
0, text.length,
Spannable.SPAN_PARAGRAPH
)
// Első sor behúzása LeadingMarginSpan-nel
spannable.setSpan(
LeadingMarginSpan.Standard(0, 20),
0, text.indexOf('\n'),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
textView.text = spannable
Jetpack Compose-ban a ParagraphStyle a TextStyle paraméterein keresztül kezelhető. Igazításhoz a textAlign, sorközhöz a lineHeight (sp-ben vagy em-ben), első sor behúzásához a textIndent használható. A Compose támogatja a LineBreak-et is a törések finom kezeléséhez (Simple, Heading, Paragraph), ami különösen hasznos többnyelvű szövegeknél.
// Jetpack Compose: ParagraphStyle TextStyle-en keresztül
Text(
text = "Első bekezdés egyedi stílussal.\n\nMásodik bekezdés behúzással.",
style = TextStyle(
textAlign = TextAlign.Justify,
lineHeight = 24.sp,
textIndent = TextIndent(firstLine = 16.sp),
lineBreak = LineBreak.Paragraph
)
)
Az Android Developers — Compose ParagraphStyle (2025) szerint a TextIndent Compose-ban történő használatakor fontos, hogy a firstLine sp-ben legyen beállítva (nem dp-ben), mivel az első sor behúzásának a szöveggel együtt kell skálázódnia. Ha a behúzás dp-ben van beállítva, a betűméret növelésekor az első sor behúzása vizuálisan kisebb lesz, ami megsérti a tipográfiai arányokat.
Flutter-ben a ParagraphStyle paradigma nincs külön osztályba szervezve — helyette a TextStyle paraméterek és kiegészítő osztályok kombinációját használják. Az igazítás TextAlign-en keresztül, a sorközök a height-on (mértékegység nélkül) keresztül, a TextHeightBehavior pedig az első és utolsó sor látható behúzásait kezeli.
// Flutter: ParagraphStyle Text paramétereken keresztül
Text(
'Stilizált bekezdés Flutterben.\n\nMásodik bekezdés behúzásokkal.',
style: TextStyle(
fontSize: 16,
height: 1.5,
leadingDistribution: TextLeadingDistribution.proportional,
),
textAlign: TextAlign.justify,
textHeightBehavior: TextHeightBehavior(
applyHeightToFirstAscent: true,
applyHeightToLastDescent: true,
),
)
Bonyolultabb forgatókönyvekhez a Flutter a RichText használatát kínálja egyedi TextSpan-nel és WidgetSpan-nel. Ez lehetővé teszi a szöveg és inline widgetek (ikonok, képek) kombinálását egy bekezdésben, egységes formázási szabályok megtartásával. Ez a megközelítés azonban kézi töréskezelést igényel, és nem támogatja az automatikus elválasztást.
// Flutter: RichText egyedi bekezdésformázással
RichText(
text: TextSpan(
style: TextStyle(fontSize: 16, height: 1.5),
children: [
TextSpan(text: 'First paragraph with icon '),
WidgetSpan(
child: Icon(Icons.star, size: 16),
alignment: PlaceholderAlignment.middle,
),
TextSpan(text: '\n\nSecond paragraph after spacing.'),
],
),
)
A Flutter Documentation — Text Widget (2025) szerint a TextHeightBehavior kulcsfontosságú paraméter a ParagraphStyle helyes megjelenítéséhez Flutterben. Ha az applyHeightToFirstAscent false-ra van állítva, az első sor felső behúzása figyelmen kívül marad, és a szöveg a tároló felső széléhez „tapad". Ez hasznos a címeknél, de nem kívánatos a főszövegnél.
ParagraphStyle-nak figyelembe kell vennie az írás irányát minden lokalizációhoz. Az arab, héber vagy urdu (jobbról balra írás, RTL) nyelveket támogató mobilalkalmazásokban a behúzásoknak és igazításnak tükrözötten kell változniuk. Az iOS támogatja az automatikus váltást a baseWritingDirection = .natural segítségével, az Android a TextDirection-en, a Flutter a textDirection-en keresztül.
Az RTL lokalizációk igazításának konfigurálása különös figyelmet igényel. Ha LTR módban a headIndent bal behúzást állít be, RTL-ben automatikusan jobb lesz. Azonban nem minden implementáció kezeli helyesen ezt az átmenetet az igazítás explicit beállításakor (NSTextAlignment.left az NSTextAlignment.natural helyett). A Google Internationalization Guide (2025) szerint többnyelvű alkalmazásokhoz mindig natural alignment-et használj, és ellenőrizd a behúzásokat mindkét elrendezésben.
// Android: RTL támogatás ParagraphStyle-ban
val textView = TextView(context)
// Automatikus RTL támogatás engedélyezése
textView.textDirection = View.TEXT_DIRECTION_LOCALE
textView.textAlignment = View.TEXT_ALIGNMENT_TEXT_START
// Spannable RTL támogatással
val spannable = SpannableString(arabicText)
spannable.setSpan(
AlignmentSpan.Standard(Layout.Alignment.ALIGN_NORMAL),
0, arabicText.length,
Spannable.SPAN_PARAGRAPH
)
A regionális jellemzők különböző szabályokat is tartalmaznak az első sor behúzására. Az európai tipográfiában az első sor behúzása (firstLineHeadIndent) a bekezdés kiemelésének szabványa. A japán és kínai tipográfiában az első sor behúzása szintén használatos, de mérete eltérő lehet (általában 1 em az európai hagyomány 1.5 em-jével szemben). Az arab tipográfiában az első sor behúzása ritka, a bekezdéseket gyakrabban függőleges távolsággal választják el.
A leggyakoribb hiba — a ParagraphStyle használata csak a szövegmező globális attribútumain keresztül anélkül, hogy figyelembe vennénk az egyes bekezdések eltérő formázását. A több \n-nel elválasztott bekezdést tartalmazó UILabel-ben vagy TextView-ben a ParagraphStyle egyformán vonatkozik a teljes szövegre, hacsak nem használunk eltérő stílusokkal ellátott attributed-text-et minden bekezdéshez.
Az UX Collective — Common Typography Bugs in Mobile Apps (2025) szerint a ParagraphStyle-nal kapcsolatos problémák a mobilalkalmazások tipográfiai hibáinak 18%-át teszik ki. A legkritikusabb esetek, amikor a helytelen paragraphSpacing a szöveg átfedéséhez vezet különböző sorokban, vagy amikor az RTL lokalizációk LTR behúzásokkal jelennek meg. Javasolt egységteszteket készíteni minden ParagraphStyle paraméterhez különböző nyelvű teszt karakterláncokkal.
Gyakran Ismételt Kérdések
Az NSMutableParagraphStyle a bekezdésformázást kezeli (igazítás, behúzások, sorközök), míg a TextStyle a karakter attribútumokat (betűtípus, szín, méret). Mindkettő az NSAttributedString-en keresztül alkalmazható. A ParagraphStyle bekezdés szinten, a TextStyle karakterszinten működik. Egy bekezdésben több TextStyle is lehet, de ParagraphStyle — csak egy bekezdésenként.
Jetpack Compose-ban az első sor behúzása a TextIndent segítségével állítható be a TextStyle-on belül: TextStyle(textIndent = TextIndent(firstLine = 16.sp)). Az értéknek sp-ben kell lennie, hogy a szöveggel együtt skálázódjon. Többsoros szövegnél a behúzás minden új bekezdést kezdő sorra (\n karakter) vonatkozik. Az első bekezdésnél a behúzás mindig alkalmazásra kerül.
SwiftUI-ban nincs a paragraphSpacing-nak közvetlen megfelelője. A bekezdések közötti távolsághoz használj AttributedString-et (iOS 15+) NSMutableParagraphStyle-lal és paragraphSpacing tulajdonsággal. Vagy válaszd el a bekezdéseket Text("...\n\n...") segítségével, és adj hozzá .padding()-et a szövegblokkok között. Bonyolult tipográfiai forgatókönyvekhez használj NSAttributedString-et UILabelRepresentable-en keresztül.
Az Android TextView-jának nincs paragraphSpacing tulajdonsága — azt SpannableString-en keresztül LeadingMarginSpan-nel vagy egyedi LineBackgroundSpan-nel kell beállítani. Sorközhöz használj setLineSpacing-ot, bekezdések közötti távolsághoz — válaszd el a bekezdéseket extra \n-nel, vagy használj több TextView-ből álló összetett tárolót.
A helyes ParagraphStyle javítja az akadálymentesítést: a megfelelő paragraphSpacing segíti a kognitív zavarokkal élő felhasználókat a bekezdéshatárok jobb felismerésében. A WCAG 2.2 a bekezdések vizuális elválasztását ajánlja (behúzás vagy távolság). A paragraphSpacing nem lehet kisebb, mint 1.5 × line-height. RTL lokalizációknál ellenőrizd, hogy a behúzások tükrözötten jelenjenek meg.
Összefoglaló
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is