【Delphi】開發IOS 程序,TLabel 中英文字對齊(水平),一行代碼解決顯示對齊問題!

目錄

一、問題現象:

二、解決方案(一行代碼解決ios對齊問題):

三、解決后效果:

四、后記:


一、問題現象:

????????在用 Delphi 開發ios程序時,使用TLabel控件顯示,會出現中英文無法水平對齊,英文字符會靠上大概少半行,看起來很不協調。

????????如下圖所示:

????????出現這樣的問題,從 ios 9 開始就一直存在。目前測試的11.3仍然存在這個問題!所以特寫出此解決方案,以方便需要的朋友!

二、解決方案(一行代碼解決ios對齊問題):

????????由于 Delphi 的版本比較多,不同的版本解決方案基本一致,但都是需要修該對應版本的FMX.FontGlyphs.iOS.pas文件。如果默認安裝,一般該文件位于C:\Program Files (x86)\Embarcadero\Studio\22.0\source\fmx目錄下,注意22.0表示版本,不同的版本這個數字不一樣。

  1. 找到 FMX.FontGlyphs.iOS.pas?這個文件;
  2. 將該文件拷貝到你的工程文件目錄下(也就是你正在開發的工程文件);
  3. 修改拷貝后的?FMX.FontGlyphs.iOS.pas 文件;

? ? ? ? 本文使用的是D11.3版本,修改?FMX.FontGlyphs.iOS.pas 這個文件中的這個過程?GetDefaultBaseline 。就是修改205行,將 Chars := 'a'; 修改為 Chars := '中';

重點:

????????在工程文件中引用修改后的 FMX.FontGlyphs.iOS.pas?文件。

? {$IFDEF ?IOS}
? ? ? FMX.FontGlyphs.iOS, ? ?//IOS 對齊
? {$ENDIF}

修改前文件

{*******************************************************}
{                                                       }
{             Delphi FireMonkey Platform                }
{ Copyright(c) 2012-2023 Embarcadero Technologies, Inc. }
{              All rights reserved                      }
{                                                       }
{*******************************************************}unit FMX.FontGlyphs.iOS;interface{$SCOPEDENUMS ON}usesSystem.Math, System.Types, System.Classes, System.SysUtils, System.UITypes, System.UIConsts, System.Generics.Collections,System.Generics.Defaults, Macapi.ObjectiveC, Macapi.CoreFoundation, iOSapi.CocoaTypes, iOSapi.CoreGraphics,iOSapi.Foundation, iOSapi.CoreText, iOSapi.UIKit, FMX.Types, FMX.Surfaces, FMX.FontGlyphs;typeTIOSFontGlyphManager = class(TFontGlyphManager)constBoundsLimit = $FFFF;privateFColorSpace: CGColorSpaceRef;FFontRef: CTFontRef;FColoredEmojiFontRef: CTFontRef;FDefaultBaseline: Single;FDefaultVerticalAdvance: Single;procedure GetDefaultBaseline;function GetFontDescriptor: CTFontDescriptorRef;function CGColorCreate(const AColor: TAlphaColor): CGColorRef;function CTFrameCreate(const APath: CGMutablePathRef; const ACharacter: string): CTFrameRef;protectedprocedure LoadResource; override;procedure FreeResource; override;function DoGetGlyph(const ACharacter: UCS4String; const Settings: TFontGlyphSettings;const UseColorfulPalette: Boolean): TFontGlyph; override;function DoGetBaseline: Single; override;function IsColorfulCharacter(const ACharacter: UCS4String): Boolean; override;publicconstructor Create;destructor Destroy; override;end;implementationusesSystem.Character, System.Math.Vectors, Macapi.Helpers, FMX.Graphics, FMX.Consts, FMX.Utils;//........ 此處省略了代碼procedure TIOSFontGlyphManager.GetDefaultBaseline;
varChars: string;Str: CFStringRef;Frame: CTFrameRef;Attr: CFMutableAttributedStringRef;Path: CGMutablePathRef;Bounds: CGRect;FrameSetter: CTFramesetterRef;// MetricsLine: CTLineRef;Lines: CFArrayRef;Runs: CFArrayRef;Run: CTRunRef;Ascent, Descent, Leading: CGFloat;BaseLinePos: CGPoint;
beginPath := CGPathCreateMutable();Bounds := CGRectMake(0, 0, BoundsLimit, BoundsLimit);CGPathAddRect(Path, nil, Bounds);Chars := 'a';Str := CFStringCreateWithCharacters(kCFAllocatorDefault, PChar(Chars), 1);Attr := CFAttributedStringCreateMutable(kCFAllocatorDefault, 0);CFAttributedStringReplaceString(Attr, CFRangeMake(0, 0), Str);CFAttributedStringBeginEditing(Attr);try// Fontif FFontRef <> nil thenCFAttributedStringSetAttribute(Attr, CFRangeMake(0, 1), kCTFontAttributeName, FFontRef);finallyCFAttributedStringEndEditing(Attr);end;FrameSetter := CTFramesetterCreateWithAttributedString(CFAttributedStringRef(Attr));CFRelease(Attr);Frame := CTFramesetterCreateFrame(FrameSetter, CFRangeMake(0, 0), Path, nil);CFRelease(FrameSetter);CFRelease(Str);// MetricsLines := CTFrameGetLines(Frame);Line := CTLineRef(CFArrayGetValueAtIndex(Lines, 0));Runs := CTLineGetGlyphRuns(Line);Run := CFArrayGetValueAtIndex(Runs, 0);CTRunGetTypographicBounds(Run, CFRangeMake(0, 1), @Ascent,  @Descent, @Leading);CTFrameGetLineOrigins(Frame, CFRangeMake(0, 0), @BaseLinePos);FDefaultBaseline := BoundsLimit - BaseLinePos.y;FDefaultVerticalAdvance := FDefaultBaseline + Descent;CFRelease(Frame);CFRelease(Path);
end;//........ 此處省略了代碼

修改后文件

{*******************************************************}
{                                                       }
{             Delphi FireMonkey Platform                }
{ Copyright(c) 2012-2023 Embarcadero Technologies, Inc. }
{              All rights reserved                      }
{                                                       }
{*******************************************************}unit FMX.FontGlyphs.iOS;interface{$SCOPEDENUMS ON}usesSystem.Math, System.Types, System.Classes, System.SysUtils, System.UITypes, System.UIConsts, System.Generics.Collections,System.Generics.Defaults, Macapi.ObjectiveC, Macapi.CoreFoundation, iOSapi.CocoaTypes, iOSapi.CoreGraphics,iOSapi.Foundation, iOSapi.CoreText, iOSapi.UIKit, FMX.Types, FMX.Surfaces, FMX.FontGlyphs;typeTIOSFontGlyphManager = class(TFontGlyphManager)constBoundsLimit = $FFFF;privateFColorSpace: CGColorSpaceRef;FFontRef: CTFontRef;FColoredEmojiFontRef: CTFontRef;FDefaultBaseline: Single;FDefaultVerticalAdvance: Single;procedure GetDefaultBaseline;function GetFontDescriptor: CTFontDescriptorRef;function CGColorCreate(const AColor: TAlphaColor): CGColorRef;function CTFrameCreate(const APath: CGMutablePathRef; const ACharacter: string): CTFrameRef;protectedprocedure LoadResource; override;procedure FreeResource; override;function DoGetGlyph(const ACharacter: UCS4String; const Settings: TFontGlyphSettings;const UseColorfulPalette: Boolean): TFontGlyph; override;function DoGetBaseline: Single; override;function IsColorfulCharacter(const ACharacter: UCS4String): Boolean; override;publicconstructor Create;destructor Destroy; override;end;implementationusesSystem.Character, System.Math.Vectors, Macapi.Helpers, FMX.Graphics, FMX.Consts, FMX.Utils;//........ 此處省略了代碼procedure TIOSFontGlyphManager.GetDefaultBaseline;
varChars: string;Str: CFStringRef;Frame: CTFrameRef;Attr: CFMutableAttributedStringRef;Path: CGMutablePathRef;Bounds: CGRect;FrameSetter: CTFramesetterRef;// MetricsLine: CTLineRef;Lines: CFArrayRef;Runs: CFArrayRef;Run: CTRunRef;Ascent, Descent, Leading: CGFloat;BaseLinePos: CGPoint;
beginPath := CGPathCreateMutable();Bounds := CGRectMake(0, 0, BoundsLimit, BoundsLimit);CGPathAddRect(Path, nil, Bounds);Chars := '中';//Chars := 'a';Str := CFStringCreateWithCharacters(kCFAllocatorDefault, PChar(Chars), 1);Attr := CFAttributedStringCreateMutable(kCFAllocatorDefault, 0);CFAttributedStringReplaceString(Attr, CFRangeMake(0, 0), Str);CFAttributedStringBeginEditing(Attr);try// Fontif FFontRef <> nil thenCFAttributedStringSetAttribute(Attr, CFRangeMake(0, 1), kCTFontAttributeName, FFontRef);finallyCFAttributedStringEndEditing(Attr);end;FrameSetter := CTFramesetterCreateWithAttributedString(CFAttributedStringRef(Attr));CFRelease(Attr);Frame := CTFramesetterCreateFrame(FrameSetter, CFRangeMake(0, 0), Path, nil);CFRelease(FrameSetter);CFRelease(Str);// MetricsLines := CTFrameGetLines(Frame);Line := CTLineRef(CFArrayGetValueAtIndex(Lines, 0));Runs := CTLineGetGlyphRuns(Line);Run := CFArrayGetValueAtIndex(Runs, 0);CTRunGetTypographicBounds(Run, CFRangeMake(0, 1), @Ascent,  @Descent, @Leading);CTFrameGetLineOrigins(Frame, CFRangeMake(0, 0), @BaseLinePos);FDefaultBaseline := BoundsLimit - BaseLinePos.y;FDefaultVerticalAdvance := FDefaultBaseline + Descent;CFRelease(Frame);CFRelease(Path);
end;//........ 此處省略了代碼

三、解決后效果:

????????已經全部水平對齊,完美解決!

四、后記:

????????記得當時在使用D10.1 berlin的時候,就存在這個問題。中間一直在沒有用Delphi開發過ios程序,當時以為高版本的Delphi 可能會解決這個問題,沒想到D11.3仍然存在這個問題,不知道是否是在什么地方配置下就可以解決(如果確實有知道的請留言告知)。幸好當時解決有記錄,今天遇到問題還可以繼續使用。這要感謝媽媽教我的:閑時收拾,忙時用!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/160305.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/160305.shtml
英文地址,請注明出處:http://en.pswp.cn/news/160305.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

WiFi 6的數據在發送端分片和在接收端重組的理解

802.11ax是WiFi 6標準&#xff0c;其引入了一些新的特性和技術來提升無線網絡的性能&#xff0c;其中包括幀聚合和幀分片。以下是它們的詳細處理流程&#xff1a; 1. 幀聚合 幀聚合是一種提高傳輸效率的技術&#xff0c;它允許多個數據幀被聚合到一起&#xff0c;然后作為一個…

layui(2.8.18)生成驗證碼

<!DOCTYPE html> <html> <head><meta charset"utf-8"><title>登入</title><meta name"renderer" content"webkit"><meta http-equiv"X-UA-Compatible" content"IEedge,chrome1&quo…

Go 工具鏈詳解(七):模塊緩存清理工具

go mod 緩存 在 Golang 中&#xff0c;模塊是對一組版本化的包的集合的描述。Go 1.11 版本引入了模塊支持&#xff0c;通過 go mod 命令提供了對模塊的管理。Go 模塊的一個重要特性是依賴管理&#xff0c;可以清晰地定義項目所依賴的模塊及對應的版本&#xff0c;并確保代碼使…

電磁優化的并行空間映射方法

空間映射(SM)是一種公認的加速電磁優化的方法。現有的SM方法大多基于順序計算機制。本文提出了一種用于電磁優化的并行SM方法。在該方法中&#xff0c;每次迭代開發的代理模型被訓練以同時匹配多個點的精細模型。多點訓練和SM使代理模型在比標準SM更大的鄰域內有效。本文提出的…

[補題記錄] Complete the Permutation(貪心、set)

URL&#xff1a;https://codeforces.com/group/OcmZ7weh45/contest/487583/problem/J 目錄 Problem/題意 Thought/思路 Code/代碼 Problem/題意 給出一個長度為 N 的序列&#xff0c;其中的元素都是奇數。 現在要求在兩個奇數之間插入一個偶數&#xff0c;使得這三個數遞增…

信息壓縮模型在自然語言處理中的應用和探討

信息壓縮模型在自然語言處理中的應用和探討 摘要:正文:結論:附錄:摘要: 隨著人工智能和深度學習的發展,自然語言處理(NLP)在信息處理中的角色變得越來越重要。然而,海量的自然語言數據為信息處理帶來了挑戰——更多的信息通常意味著更高的處理成本,并可能導致效率降低。為…

一個工具讓你明白“萬丈高樓平地起”,拒絕重復造輪子!

大家在公司工作當中是不是很多時間裝環境很麻煩&#xff0c;一個項目要上線了&#xff0c;開始網上搜了一邊又一遍的環境搭建教程&#xff1f;等到下一個項目要上線了&#xff0c;又上網上搜了一邊又一遍的環境搭建教程。關鍵天花亂墜的互聯網&#xff0c;找不到很靠譜的呀。有…

數組的移動

設計程序&#xff0c;給定包含N個整數的數組array&#xff0c;實現操作&#xff1a;前面各個整數順序向后移動m個位置&#xff0c;最后的m個整數移動到最前面。方法&#xff1a;void move(int array[], int n,int m ) 輸入要求 第一行輸入兩個整數N(1<N<1e6)和m(0<m&…

webpack 配置

1、基礎配置 // node js核心模塊 const path require(path) // 插件是需要引入使用的 const ESLintPlugin require(eslint-webpack-plugin) // 自動生成index.html const HtmlWebpackPlugin require(html-webpack-plugin); // 將css文件單獨打包&#xff0c;在index.html中…

如何做好項目管理?年薪百萬項目大佬一直在用這11張圖

大家好&#xff0c;我是老原。 日常工作中&#xff0c;我們會遇到各種大大小小的工作項目&#xff0c;如何能讓項目保質保量的完成&#xff0c;是我們項目經理的目標。 項目管理的流程可以說是由一系列的子過程組成的&#xff0c;它是一個循序漸進的過程&#xff0c;所以不能…

python數字

目錄 整數&#xff08;如&#xff0c;2、4、20 &#xff09;的類型是 int&#xff0c;帶小數&#xff08;如&#xff0c;5.0、1.6 &#xff09;的類型是 float。 Python 用 ** 運算符計算乘方 1&#xff1a; 等號&#xff08;&#xff09;用于給變量賦值。 解釋器像一個簡單…

進程API

linux下進程的api forkwaitexec fork #include <stdio.h> #include <stdlib.h> #include <unistd.h>/* linux環境運行 子進程并不是完全拷貝了父進程。具體來說&#xff0c;雖然它擁有自己的 地址空間&#xff08;即擁有自己的私有內存&#xff09;、寄存器…

【Delphi】使用TWebBrowser執行JavaScript命令傳入JSON參數執行出錯解決方案

目錄 一、問題背景&#xff1a; 二、實際示例&#xff1a; 三、解決方案&#xff1a; 1. Delphi 代碼&#xff1a; 2. javaScript代碼&#xff1a; 一、問題背景&#xff1a; 在用Delphi開發程序&#xff0c;無論是移動端還是PC端&#xff0c;都可以很方便的使用TWebBrows…

Postman如何使用(一):導入導出和發送請求查看響應

一、Postman如何導入導出打包的應用 在Postman中導入導出我們的 測試數據包 和 工作環境 非常的方便&#xff1a; 導出數據包的方法如下&#xff1a; 如果你想學習自動化測試&#xff0c;我這邊給你推薦一套視頻&#xff0c;這個視頻可以說是B站播放全網第一的自動化測試教程…

七天.NET 8操作SQLite入門到實戰 - 第三天SQLite快速入門

前言 今天我們花費一個小時快速了解SQLite數據類型、SQLite常用命令和語法。 七天.NET 8操作SQLite入門到實戰詳細教程 第一天 SQLite 簡介第二天 在 Windows 上配置 SQLite環境 EasySQLite項目源碼地址 GitHub地址&#xff1a;https://github.com/YSGStudyHards/EasySQLite&…

第一百七十六回 如何創建漸變色邊角

文章目錄 1. 概念介紹2. 實現方法3. 代碼與細節3.1 示例代碼3.2 代碼細節 4. 內容總結 我們在上一章回中介紹了"如何創建放射形狀漸變背景"相關的內容&#xff0c;本章回中將介紹"如何創建漸變色邊角".閑話休提&#xff0c;讓我們一起Talk Flutter吧。 1.…

2023-11-22 LeetCode每日一題(網格中的最小路徑代價)

2023-11-22每日一題 一、題目編號 2304. 網格中的最小路徑代價二、題目鏈接 點擊跳轉到題目位置 三、題目描述 給你一個下標從 0 開始的整數矩陣 grid &#xff0c;矩陣大小為 m x n &#xff0c;由從 0 到 m * n - 1 的不同整數組成。你可以在此矩陣中&#xff0c;從一個…

一石激起千層浪,有關奧特曼被炒的消息引發了一場熱烈的討論

在毫無征兆的情況下&#xff0c;OpenAI CEO山姆-奧特曼被炒了。 一石激起千層浪&#xff0c;有關奧特曼被炒的消息引發了一場熱烈的討論。 有人將其看成是一場「宮斗」&#xff0c;有人將其看成是OpenAI的董事會與創始人們的一次糾偏。 無論如何&#xff0c;這樣一件看似并無…

網工內推 | 合資公司網工,CCNP/HCIP認證優先,朝九晚六

01 中企網絡通信技術有限公司 招聘崗位&#xff1a;網絡工程師 職責描述&#xff1a; 1、按照工作流程和指引監控網絡運行情況和客戶連接狀況&#xff1b; 2、確保各監控系統能正常運作&#xff1b; 3、快速響應各個網絡告警事件&#xff1b; 4、判斷出網絡故障&#xff0c;按…