如何根据条件添加其他属性?
在下面的代码中,我收到错误Cannot assign value of type 'some View' (result of 'Self.overlay(_:alignment:)') to type 'some View' (result of 'Self.onTapGesture(count:perform:)')
import SwiftUI
struct ConditionalProperty: View {
@State var overlay: Bool
var body: some View {
var view = Image(systemName: "photo")
.resizable()
.onTapGesture(count: 2, perform: self.tap)
if self.overlay {
view = view.overlay(Circle().foregroundColor(Color.red))
}
return view
}
func tap() {
// ...
}
}
答案 0 :(得分:6)
感谢this post,我发现了一个界面非常简单的选项:
Text("Hello")
.if(shouldBeRed) { $0.foregroundColor(.red) }
通过此扩展程序启用:
extension View {
@ViewBuilder
func `if`<Transform: View>(_ condition: Bool, transform: (Self) -> Transform) -> some View {
if condition { transform(self) }
else { self }
}
}
这是一篇很棒的博客文章,其中包含有关条件修饰符的其他提示:https://fivestars.blog/swiftui/conditional-modifiers.html
答案 1 :(得分:4)
Rob Mayoff已经很好地解释了为什么出现此行为,并提出了两种解决方案(透明叠加层或使用AnyView
)。第三种更优雅的方法是使用ConditionalContent。
创建ConditionalContent的一种简单方法是在组或堆栈中编写if
else
语句。这是一个使用组的示例:
import SwiftUI
struct ConditionalProperty: View {
@State var overlay: Bool
var body: some View {
Group {
if overlay {
base.overlay(Circle().foregroundColor(Color.red))
} else {
base
}
}
}
var base: some View {
Image("photo")
.resizable()
.onTapGesture(count: 2, perform: self.tap)
}
func tap() {
// ...
}
}
答案 2 :(得分:3)
在SwiftUI术语中,您没有添加属性。您正在添加修饰符。
这里的问题是,在SwiftUI中,每个修饰符都返回一个取决于其修改内容的类型。
var view = Image(systemName: "photo")
.resizable()
.onTapGesture(count: 2, perform: self.tap)
// view has some deduced type like GestureModifier<SizeModifier<Image>>
if self.overlay {
let newView = view.overlay(Circle().foregroundColor(Color.red))
// newView has a different type than view, something like
// OverlayModifier<GestureModifier<SizeModifier<Image>>>
}
由于newView
与view
的类型不同,因此您不能仅分配view = newView
。
解决此问题的一种方法是始终使用overlay
修饰符,但在不希望覆盖层可见时使其透明:
var body: some View {
return Image(systemName: "photo")
.resizable()
.onTapGesture(count: 2, perform: self.tap)
.overlay(Circle().foregroundColor(overlay ? .red : .clear))
}
另一种处理方法是使用类型橡皮擦AnyView
:
var body: some View {
let view = Image(systemName: "photo")
.resizable()
.onTapGesture(count: 2, perform: self.tap)
if overlay {
return AnyView(view.overlay(Circle().foregroundColor(.red)))
} else {
return AnyView(view)
}
}
我从Apple工程师那里看到的建议是避免使用AnyView
,因为它比使用完全类型的视图效率低。例如this tweet和this tweet。
答案 3 :(得分:2)
这是与Kiran Jasvanee发布的答案类似的答案,但简化了:
struct ContentView: View {
var body: some View {
Text("Hello, World!")
.modifier(ConditionalModifier(isBold: true))
}
}
struct ConditionalModifier: ViewModifier {
var isBold: Bool
func body(content: Content) -> some View {
Group {
if self.isBold {
content.font(.custom("HelveticaNeue-Bold", size: 14))
}
else{
content.font(.custom("HelveticaNeue", size: 14))
}
}
}
}
区别在于无需添加此扩展名:
extension View {
func conditionalView(_ value: Bool) -> some View {
self.modifier(ConditionalModifier(isBold: value))
}
}
在ConditionalModifier
结构中,您也可以消除“组”视图,而使用@ViewBuilder
装饰器,如下所示:
struct ConditionalModifier: ViewModifier {
var isBold: Bool
@ViewBuilder
func body(content: Content) -> some View {
// Group {
if self.isBold {
content.font(.custom("HelveticaNeue-Bold", size: 14))
}
else{
content.font(.custom("HelveticaNeue", size: 14))
}
// }
}
}
如果要有条件地显示视图,则必须使用“组”视图(或其他父视图)或@ViewBuilder
装饰器。
这是另一个示例,其中按钮的文本可以在粗体和非粗体之间切换:
struct ContentView: View {
@State private var makeBold = false
var body: some View {
Button(action: {
self.makeBold.toggle()
}, label: {
Text("Tap me to Toggle Bold")
.modifier(ConditionalModifier(isBold: makeBold))
})
}
}
struct ConditionalModifier: ViewModifier {
var isBold: Bool
func body(content: Content) -> some View {
Group {
if self.isBold {
content.font(.custom("HelveticaNeue-Bold", size: 14))
}
else{
content.font(.custom("HelveticaNeue", size: 14))
}
}
}
}
答案 4 :(得分:0)
我认为实现#include "stdio.h"
#include "stdlib.h"
#include "string.h"
typedef struct {
int size;
int id;
int tip;
float x1;
float x2;
float y1;
float y2;
}blocks;
int main() {
blocks *block1 , *block2 , *block3;
char line[60];
int blcNum=1;
int sizer=0;
int temp;
block1 = malloc( sizeof(blocks) );
block2 = malloc( sizeof(blocks) );
block3 = malloc( sizeof(blocks) );
FILE *fp;
fp = fopen("test_system.txt","r");
// block's size calculator and memory allocater ;
while(fgets(line,60,fp))
{
if ( strstr(line,"\0") != NULL && strstr(line,"ID") == NULL && strstr(line,"END") == NULL ) {
sizer++;
}
else if ( strstr(line,"END") != NULL ){
if ( blcNum == 1){
block1->size = sizer;
blcNum++;
sizer = 0;
}
else if ( blcNum == 2){
block2->size = sizer;
blcNum++;
sizer = 0;
}
else if ( blcNum == 3){
block3->size = sizer;
blcNum++;
sizer = 0;
}
}
};
block1 = realloc(block1 , block1->size * sizeof(blocks));
block2 = realloc(block2 , block2->size * sizeof(blocks));
block3 = realloc(block3 , block3->size * sizeof(blocks));
fclose(fp);
line == NULL;
blcNum=1;
puts("\n\n");
fp = fopen("test_system.txt","r");
char *szTempString;
int index=1;
while(fgets(line,60,fp))
{
szTempString = line;
if( strstr(line,"ID") == NULL && strstr(line,"END") == NULL )
{
printf("%s",line);
if(index <= block1->size)
{
printf("%s",line);
sscanf(szTempString,"%d %f %f",&(block1 + (index*sizeof(blocks)))->id,
&(block1 + (index*sizeof(blocks)))->x1,
&(block1 + (index*sizeof(blocks)))->y1);
index++;
}
}
}
fclose(fp);
printf("\nUploader's information : \n");
for (temp =1; temp <= block1->size ; ++temp)
{
printf(" id : %d , X1 : %f , Y1 : %f \n",(block1+(temp*sizeof(block1)))->id,(block1+(temp*sizeof(block1)))->x1,(block1+(temp*sizeof(block1)))->y1);
puts("\nIt must be \nid : 1 , X1 : 1.00 , Y1 : 1.00");
}
printf("\n1 . block's size : %d ",block1->size);
printf("\n2 . block's size : %d ",block2->size);
printf("\n3 . block's size : %d ",block3->size);
free(block1);
free(block2);
free(block3);
return 0;
}
的首选方法如下。如果应用了动画,效果会很好。
我尝试了其他几种方法,但这会影响我应用的动画。
您可以添加条件以代替我保留 .conditionalView(final InputStream file = new FileInputStream("file path");
EnvironmentHelper environmentHelper = mock(EnvironmentHelper.class);
Properties properties = new Properties();
System system = mock(System.class);
when(system.getProperties()).thenReturn(properties);
when(environmentHelper.isRunningInProductionMode(properties)).thenReturn(true);
when(featureDAO.findActiveEnabledFeatures(anyList())).thenReturn(new ArrayList<>());
)的错误。
下面,您可以切换到Conditional Properties
来检查“世界,您好!” 会显示为 BOLD 。
false
答案 5 :(得分:0)
就这么简单
float watermarkTrimmingRectangleWidth = 500;
float watermarkTrimmingRectangleHeight = 500;
float formWidth = 500;
float formHeight = 500;
float formXOffset = -40;
float formYOffset = 0;
float xTranslation = 50;
float yTranslation = 25;
double rotationInRads = Math.PI / 4.2;
PdfDocument pdfDoc = new PdfDocument(new PdfReader(filePath), new PdfWriter(destinationfile));
var numberOfPages = pdfDoc.GetNumberOfPages();
PdfPage page = null;
for (var i = 1; i <= numberOfPages; i++)
{
page = pdfDoc.GetPage(i);
Rectangle ps = page.GetPageSize();
float bottomLeftX = ps.GetWidth() / 2 - watermarkTrimmingRectangleWidth / 2;
float bottomLeftY = ps.GetHeight() / 2 - watermarkTrimmingRectangleHeight / 2;
Rectangle watermarkTrimmingRectangle = new Rectangle(bottomLeftX, bottomLeftY, ps.GetWidth(), watermarkTrimmingRectangleHeight);
PdfWatermarkAnnotation watermark = new PdfWatermarkAnnotation(watermarkTrimmingRectangle);
AffineTransform transform = new AffineTransform();
transform.Translate(xTranslation, yTranslation);
transform.Rotate(rotationInRads);
PdfFixedPrint fixedPrint = new PdfFixedPrint();
watermark.SetFixedPrint(fixedPrint);
Rectangle formRectangle = new Rectangle(formXOffset, formYOffset, formWidth, formHeight);
//Observation: font XObject will be resized to fit inside the watermark rectangle
PdfFormXObject form = new PdfFormXObject(formRectangle);
PdfExtGState gs1 = new PdfExtGState().SetFillOpacity(0.8f).SetStrokeOpacity(1.5f);
PdfCanvas canvas = new PdfCanvas(form, pdfDoc);
float[] transformValues = new float[6];
transform.GetMatrix(transformValues);
canvas.SaveState()
.BeginText().SetExtGState(gs1)
.SetTextMatrix(transformValues[0], transformValues[1], transformValues[2], transformValues[3], transformValues[4], transformValues[5])
.SetFontAndSize(font, fontSize)
.ShowText("Restricted Internal")
.EndText()
.RestoreState();
canvas.Release();
watermark.SetAppearance(PdfName.N, new PdfAnnotationAppearance(form.GetPdfObject()));
watermark.SetFlags(PdfAnnotation.READ_ONLY);
page.AddAnnotation(watermark);
}
page?.Flush();
pdfDoc.Close();