UE 實現英雄聯盟手游 備注名文本超框自動截斷
UE 實現英雄聯盟手游 備注名文本超框自動截斷
效果如圖

需求由來
- 策劃要求
實現流程
- UTextBlock 新增一個超框截斷功能開關
- 獲取TextBlock的Size X長度
- 獲取STextBlock文本渲染需要長度
- 判斷文本長度是否超過設計長度
- 循環減少字符直至滿足設計長度
關鍵代碼(這里只展示修改源碼情況 也可以使用繼承 復寫)
-
UTextBlock.h
public: /** 超框自動截斷 填補"..." */ UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=Appearance, AdvancedDisplay) bool bAutoCut; protected: virtual TSharedRef<SWidget> RebuildWidget() override; -
UTextBlock.cpp
TSharedRef<SWidget> UTextBlock::RebuildWidget() { if (bWrapWithInvalidationPanel && !IsDesignTime()) { TSharedPtr<SWidget> RetWidget = SNew(SInvalidationPanel) [ SAssignNew(MyTextBlock, STextBlock) .SimpleTextMode(bSimpleTextMode) ]; return RetWidget.ToSharedRef(); } else { MyTextBlock = SNew(STextBlock) .SimpleTextMode(bSimpleTextMode); MyTextBlock->SetAutoCut(bAutoCut); return MyTextBlock.ToSharedRef(); } } -
STextBlock.h
private: /** 超框自動截斷 填補"..." */ bool bAutoCut = false; public: void SetAutoCut(bool AutoCut); -
STextBlock.cpp
void STextBlock::SetAutoCut(bool AutoCut) { bAutoCut = AutoCut; } FVector2D STextBlock::ComputeDesiredSize(float LayoutScaleMultiplier) const { SCOPE_CYCLE_COUNTER(Stat_SlateTextBlockCDS); if (bSimpleTextMode) { const FVector2D LocalShadowOffset = GetShadowOffset(); const float LocalOutlineSize = GetFont().OutlineSettings.OutlineSize; // Account for the outline width impacting both size of the text by multiplying by 2 // Outline size in Y is accounted for in MaxHeight calculation in Measure() const FVector2D ComputedOutlineSize(LocalOutlineSize * 2, LocalOutlineSize); const FVector2D TextSize = FSlateApplication::Get().GetRenderer()->GetFontMeasureService()->Measure(GetText(), GetFont()) + ComputedOutlineSize + LocalShadowOffset; CachedSimpleDesiredSize = FVector2D(FMath::Max(MinDesiredWidth.Get(0.0f), TextSize.X), TextSize.Y); return CachedSimpleDesiredSize.GetValue(); } else { if (bAutoCut != true) { // ComputeDesiredSize will also update the text layout cache if required const FVector2D TextSize = TextLayoutCache->ComputeDesiredSize( FSlateTextBlockLayout::FWidgetArgs(BoundText, HighlightText, WrapTextAt, AutoWrapText, WrappingPolicy, TransformPolicy, Margin, LineHeightPercentage, Justification), LayoutScaleMultiplier, GetComputedTextStyle() ); return FVector2D(FMath::Max(MinDesiredWidth.Get(0.0f), TextSize.X), TextSize.Y); } else { TAttribute<FText> DisplayText = BoundText; const FString BoundString = BoundText.Get(FText::GetEmpty()).ToString(); int Lenght = 0; do { const FVector2D TextSize = TextLayoutCache->ComputeDesiredSize( FSlateTextBlockLayout::FWidgetArgs(DisplayText, HighlightText, WrapTextAt, AutoWrapText, WrappingPolicy, TransformPolicy, Margin, LineHeightPercentage, Justification), LayoutScaleMultiplier, GetComputedTextStyle() ); const FVector2D DisplayTextSize = FVector2D(FMath::Max(MinDesiredWidth.Get(0.0f), TextSize.X), TextSize.Y); //容器寬度大于文本顯示寬度 if (GetTickSpaceGeometry().GetLocalSize().X >= DisplayTextSize.X) { return DisplayTextSize; } Lenght++; //處理截取到最后一個字符 還超框的情況 if (Lenght == BoundString.Len()) { return DisplayTextSize; } FString NewBoundString = BoundString.Left(BoundString.Len() - Lenght) + "..."; FText NewText = FText::FromString(NewBoundString); DisplayText = TAttribute<FText>::Create(TAttribute<FText>::FGetter::CreateLambda( [NewText]() { return NewText; })); } while (true); } } }

浙公網安備 33010602011771號