8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

如何使用自定义字体和颜色在 SwiftUI Picker 中自定义文本?

Mourad BENKDOUR 3月前

81 0

我正在尝试自定义 SwiftUI Picker 中的文本以使用特定的自定义字体和颜色。但是,我无法正确应用自定义样式。这是我目前的实现...

我正在尝试自定义 SwiftUI Picker 中的文本以使用特定的自定义字体和颜色。但是,我无法正确应用自定义样式。这是我当前的实现:

import Foundation
import SwiftUI

// Enums for Filter and Sort Options
enum EventFilter: String, CaseIterable, Identifiable {
    case all = "All"
    case liked = "Liked"
    case attending = "Attending"
    case pendingApproval = "Pending Approval"

    var id: String { self.rawValue }
}

enum EventSort: String, CaseIterable, Identifiable {
    case date = "Date"
    case title = "Title"

    var id: String { self.rawValue }
}

// Color Utils for Custom Colors
struct ColorUtils {
    static let darkPurple = Color(red: 51 / 255, green: 0 / 255, blue: 102 / 255)
    static let lightPurple = Color(red: 245 / 255, green: 240 / 255, blue: 255 / 255)
}

// Filter and Sort View
struct FilterSortView: View {
    @Binding var selectedFilter: EventFilter
    @Binding var selectedSort: EventSort

    var body: some View {
        HStack {
            Picker("Filter", selection: $selectedFilter) {
                ForEach(EventFilter.allCases) { filter in
                    Text(filter.rawValue)
                        .font(.custom("samble", size: 16))
                        .foregroundColor(ColorUtils.darkPurple)
                        .tag(filter)
                }
            }
            .pickerStyle(MenuPickerStyle())

            Picker("Sort", selection: $selectedSort) {
                ForEach(EventSort.allCases) { sort in
                    Text(sort.rawValue)
                        .font(.custom("samble", size: 16))
                        .foregroundColor(ColorUtils.darkPurple)
                        .tag(sort)
                }
            }
            .pickerStyle(MenuPickerStyle())
        }
        .padding()
    }
}

// Preview
struct FilterSortView_Previews: PreviewProvider {
    @State static var selectedFilter: EventFilter = .all
    @State static var selectedSort: EventSort = .date

    static var previews: some View {
        FilterSortView(selectedFilter: $selectedFilter, selectedSort: $selectedSort)
            .previewLayout(.sizeThatFits)
    }
}

问题:我无法将自定义字体和颜色正确应用于 Picker 中的文本。样式似乎被忽略了。

帖子版权声明 1、本帖标题:如何使用自定义字体和颜色在 SwiftUI Picker 中自定义文本?
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由Mourad BENKDOUR在本站《swift》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 我正在使用 Apple 的 RoomPlan,并且正在努力将 CapturedStructure 中的所有节点加载到 SCNNode 中。我能够浏览地板、门、窗户、墙壁和物体并重新...

    我正在使用 Apple 的 RoomPlan,并且正在努力将所有节点从加载 CapturedStructure 到 SCNNode 中。我能够浏览地板、门、窗户、墙壁和物体并在视图中渲染它们,但我正在努力在墙壁中添加整个窗户或在墙壁中添加整个 openings

    我尝试了几种解决方案,并且能够将 usdz 文件渲染到 SCNView 中,我注意到通常窗口和墙壁是成组的,这是我尝试的最后一件事。

    这是我用来将墙壁和开口合并在一起的代码,但我没有成功,甚至窗户也没有按预期工作。

        func createWallWithOpenings(wall: CapturedRoom.Surface, openings: [CapturedRoom.Surface]) -> SCNNode {
            let wallNode = SCNNode()
            
            // Define the wall geometry
            let wallWidth = CGFloat(wall.dimensions.x)
            let wallHeight = CGFloat(wall.dimensions.y)
            let wallThickness: CGFloat = 0.01
            let wallGeometry = SCNBox(width: wallWidth, height: wallHeight, length: wallThickness, chamferRadius: 0)
            
            // Create the wall node
            let wall2 = SCNNode(geometry: wallGeometry)
            wall2.simdTransform = wall.transform
    //        wall2.position = SCNVector3(wall.transform.position.x, wall.transform.position.y, wall.transform.position.z)
            
            // Create materials
            let wallMaterial = SCNMaterial()
            wallMaterial.diffuse.contents = UIColor.gray // Your wall texture or color
            wallMaterial.blendMode = .alpha
            wall2.geometry?.materials = [wallMaterial]
            
            // Add wall node to wallNode
            wallNode.addChildNode(wall2)
            
            // Subtract openings
            for opening in openings {
                if opening.parentIdentifier == wall.identifier {
                    let openingWidth = CGFloat(opening.dimensions.x)
                    let openingHeight = CGFloat(opening.dimensions.y)
                    let openingThickness: CGFloat = 0.4
                    let openingGeometry = SCNBox(width: openingWidth, height: openingHeight, length: openingThickness, chamferRadius: 0)
                    let openingNode = SCNNode(geometry: openingGeometry)
                    openingNode.simdTransform = opening.transform
    //                openingNode.position = SCNVector3(opening.transform.columns.3.x, opening.transform.columns.3.y, opening.transform.columns.3.z)
                    
                    // Create material for the opening (transparent)
                    let openingMaterial = SCNMaterial()
                    openingMaterial.diffuse.contents = UIImage(named: "window-texture.png")
                    openingMaterial.emission.contents = UIColor.clear
                    openingMaterial.isDoubleSided = true
                    openingMaterial.blendMode = .alpha
                    openingNode.geometry?.materials = [openingMaterial]
                    
                    // Subtract the opening from the wall
                    wallNode.addChildNode(openingNode)
                }
            }
            return wallNode
        }
    

    正如您在下图中看到的,您可以注意到,尽管我在场景中正确地定位了它们,但墙壁和开口都不透明。

    check that neither the opening or the window is transparent

    我将不胜感激任何帮助,因为我已经没有主意了,而且应该可以做到,因为当我渲染文件时 usdz ,我可以看到所有的节点和窗口,并且开口都在那里,而我不使用渲染的对象的唯一原因 usdz 是我丢失了一些信息,例如:

    1. 节点宽度、节点高度、材质等
  • 我知道根据上下文有不同的答案。我一直使用最常见的方式,即从 Array 到 Set 再到 Array 的链式转换。var noDuplicateArr = Array(Set(myArr))I...

    我知道根据上下文有不同的答案。我一直使用最常见的方式,即从 Array 到 Set 再到 Array 的链式转换。

    var noDuplicateArr = Array(Set(myArr))
    

    这是您喜欢的方法吗?或者您想要将方法扩展为为您执行此操作的数组?如果处理中等到大量的值,前者仍然可靠吗?

  • 遗憾的是,该问题中的大多数答案(包括大多数获得高度赞同的答案)都非常糟糕,包括直接的二次垃圾。一个好的解决方案有两个重要方面:1. 它直接从原始数组(而不是中间集合)获取元素,因此它保留了顺序,2. 它避免了双重查找(即单独

  • 转换为集合然后再转换为数组是一种简单且常见的使数组唯一的方法。但是使用这种方法不能保证保持数组的顺序,因为数组 Set 元素不是按顺序存储的。

    实现自己的函数来删除重复项总是容易出错。一个合适的替代方案是 Apple 的 swift-algorithms swift-algorithms uniqued()

    import Algorithms
    
    let animals = ["dog", "pig", "cat", "ox", "dog", "cat"]
    let uniqued = animals.uniqued()
    print(Array(uniqued)) // Prints '["dog", "pig", "cat", "ox"]'
    
    

    这将返回一个仅包含此序列的唯一元素的序列,按照每个唯一元素第一次出现的顺序排列。

  • 不错但不是新的:stackoverflow.com/a/70210590/1187415

  • 我正在开发一个 Web 应用。对于后端,我选择了 Django;对于数据库,我想使用图形数据库,因此我选择了 neo4j。有一个 Python 库 neomodel 可以与 neo4j 配合使用,还有一个特定的...

    我正在开发一个 Web 应用。对于后端,我选择了 Django;对于数据库,我想使用图形数据库,因此我选择了 neo4j。

    有一个 neomodel 可以与 neo4j 一起使用的 Python 库和一个 django_neomodel 与 Django neomodel 结合的

    我可以使用 Django 和 neo4j 从数据库中的节点检索数据,但是,我无法让它 创建 节点。

    这是我的文件的一部分 settings.py

    INSTALLED_APPS = [
        ...
        'django_neomodel',
        'neomodel',
        'corsheaders',
        'rest_framework',
        'rest_framework.authtoken',
        'rest_framework_simplejwt',
        'create',
    ]
    
    REST_FRAMEWORK = {
        'DEFAULT_AUTHENTICATION_CLASSES': [
            'rest_framework_simplejwt.authentication.JWTAuthentication',
            'rest_framework.authentication.TokenAuthentication',
        ],
    }
    
    NEOMODEL_NEO4J_BOLT_URL = 'bolt://neo4j:password@localhost:7687'
    

    以下 views.py create

    class RegisterView(View):
        """
        This view handles POST requests to create a new user in the database.
        """
        
        def post(self, request):
            new_node = myNode(
                XXX=request.POST['XXX'],
                YYY=request.POST['YYY'],
                ZZZ=request.POST['ZZZ']
            )
            new_node.save()
    

    这里是 myNode 班级:

    from neomodel import (StructuredNode, StringProperty, UniqueIdProperty)
    from .event import Event
    
    class myNode(StructuredNode):
        # Properties
        uid = UniqueIdProperty()
        XXX = StringProperty(required=True, unique_index=True)
        YYY = StringProperty(required=True)
        ZZZ = StringProperty(required=True)
    

    我收到的错误是:

    django.core.exceptions.ImproperlyConfigured: settings.DATABASES is improperly configured. Please supply the ENGINE value. Check the settings documentation for more details.
    

    我询问了 chatGPT 和 GitHub copilot,他们说我可以在设置中设置一个虚拟的 ENGINE,如下所示

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.dummy'
        }
    }
    

    但这没有帮助。

    有人知道吗?我查找了文档,但我能找到的只是这些使用 neo4j 和 Django 来访问巴拿马文件数据库的教程( 比如这里 ,但那里也只是访问数据库,但从不 创建 新节点、关系或以任何方式更改它们)。

    这有可能吗?还是我需要自己创建一个引擎?

    我使用 djangorestframework 3.15.1 , neomodel 5.3.1 neo4j 4.4.34

    我是应用开发新手。我刚开始学习,选择 Django 只是因为 Python 是我最了解的语言,所以如果你回答请写成完全新手。

  • 我正在按照这个视频教程尝试使用 DRF、djoser 和 React 实现 Google 社交身份验证。导致错误的步骤:发送 GET 请求:http://localhost:8000/auth/o/...

    我正在关注这个 视频教程 DRF , djoser 实现 Google 社交身份验证 React .

    导致错误的步骤:

    1. 发送 GET 请求:
    http://localhost:8000/auth/o/google-oauth2/?redirect_uri=http://localhost:8000
    

    响应如下所示(我稍微修改了响应,因为我不确定此 URL 是否可以安全共享)

       {
           "authorization_url": "https://accounts.google.com/o/oauth2/auth?client_id=836198290956-fe0ilujf6e23l882oumgkufi8qm6fg3m.apps.googleusercontent.com&redirect_uri=http://localhost:8000&state=eNwMFCmEplYgbUTTP9nnrQ6MduAPxzDY&response_type=code&scope=https://www.googleapis.com/auth/userinfo.email+https://www.googleapis.com/auth/userinfo.profile+openid+openid+email+profile"
       }
    
    1. 在我向浏览器输入响应后,它会将我重定向到 google sign in 页面。然后我选择我的帐户,然后按继续。我现在被重定向到 localhost:8000 这个网址 L
    http://localhost:8000/?state=eNwMFCmEplYgbUTTP9nnrQ6MduAPxzDY&code=4%2F0AcvDMrB6f3ZQuTD563Vxriu2n0VHmLEOHnDRqC6jD5BRm068jj2tyExxfZZJDFLAtcwYLg&scope=email+profile+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&authuser=0&hd=circle.help&prompt=consent
    

    我的问题出现在这里

    1. 我从该 url 中获取状态和代码参数,然后使用 Postman 向以下 url 发出 POST 请求(没有任何主体,只有 url,但我还将 Content-Type 标头设置为 application/x-www-form-urlencoded ):
    localhost:8000/auth/o/google-oauth2/?state=eNwMFCmEplYgbUTTP9nnrQ6MduAPxzDY&code=4%2F0AcvDMrB6f3ZQuTD563Vxriu2n0VHmLEOHnDRqC6jD5BRm068jj2tyExxfZZJDFLAtcwYLg
    

    但作为回应,我收到了这个( 这是我的问题 ):

    {
       "non_field_errors": [
          "Invalid state has been provided."
        ]
    }
    

    我尝试调试一下,发现原因就在这个模块上:

    # venv/lib/python3.11/site-packages/social_core/backends/oauth.py
    
    class OAuthAuth(BaseAuth):
        ...
        # Other methods
        def validate_state(self):
            """Validate state value. Raises exception on error, returns state
            value if valid."""
            if not self.STATE_PARAMETER and not self.REDIRECT_STATE:
                return None
            state = self.get_session_state()
            request_state = self.get_request_state()
            if not request_state:
                raise AuthMissingParameter(self, "state")
            elif not state:
                raise AuthStateMissing(self, "state")
            elif not constant_time_compare(request_state, state):
                raise AuthStateForbidden(self)
            else:
                return state
        ...
        # Other methods
    
    

    在我的例子中,在 OAuthAuth.validate_state() 方法中, state 变量不同于 request_state 变量,而 request_state (from OAuthAuth.validate_state() ) 与上述两个 URL 中的状态 (from urls) 相同,但 state (from OAuthAuth.validate_state() ) 完全不同。我不知道它来自哪里,为什么

    self.get_request_state()
    

    返回与 URL 不同的状态?也许我做错了什么,我应该在 Postman 中传递一些 cookie?

    UPD: 我尝试手动将正确的状态值从 url 分配给 state = self.get_session_state() 并且一切正常,我只是不知道为什么 self.get_session_state() 返回不正确的值?

    以下是我已安装的软件包的列表:

    asgiref==3.8.1
    certifi==2024.7.4
    cffi==1.16.0
    charset-normalizer==3.3.2
    cryptography==42.0.8
    defusedxml==0.8.0rc2
    Django==5.0.7
    django-filter==24.2
    django-templated-mail==1.1.1
    djangorestframework==3.15.2
    djangorestframework-simplejwt==5.3.1
    djoser==2.2.3
    idna==3.7
    Markdown==3.6
    oauthlib==3.2.2
    psycopg==3.2.1
    psycopg2-binary==2.9.9
    pycparser==2.22
    PyJWT==2.8.0
    python3-openid==3.2.0
    requests==2.32.3
    requests-oauthlib==2.0.0
    social-auth-app-django==5.4.2
    social-auth-core==4.5.4
    sqlparse==0.5.1
    typing_extensions==4.12.2
    urllib3==2.2.2
    

    这是我的设置.py

    SECRET_KEY = "django_secret_key"
    
    # SECURITY WARNING: don't run with debug turned on in production!
    DEBUG = True
    
    ALLOWED_HOSTS = []
    
    # Application definition
    
    INSTALLED_APPS = [
        "django.contrib.admin",
        "django.contrib.auth",
        "django.contrib.contenttypes",
        "django.contrib.sessions",
        "django.contrib.messages",
        "django.contrib.staticfiles",
    
        # Third party apps
        "rest_framework",
        "djoser",
        "social_django",
        "rest_framework_simplejwt",
        "rest_framework_simplejwt.token_blacklist",  # more smooth with migration
    
        # My apps
        "accounts"
    ]
    
    MIDDLEWARE = [
        "social_django.middleware.SocialAuthExceptionMiddleware",
        "django.middleware.security.SecurityMiddleware",
        "django.contrib.sessions.middleware.SessionMiddleware",
        "django.middleware.common.CommonMiddleware",
        "django.middleware.csrf.CsrfViewMiddleware",
        "django.contrib.auth.middleware.AuthenticationMiddleware",
        "django.contrib.messages.middleware.MessageMiddleware",
        "django.middleware.clickjacking.XFrameOptionsMiddleware",
    ]
    
    ROOT_URLCONF = "djSocAuth.urls"
    
    TEMPLATES = [
        {
            "BACKEND": "django.template.backends.django.DjangoTemplates",
            # "DIRS": [BASE_DIR / 'templates'],  # os.path.join(BASE_DIR, "build")
            "DIRS": [os.path.join(BASE_DIR, "build")],  # os.path.join(BASE_DIR, "build")
            "APP_DIRS": True,
            "OPTIONS": {
                "context_processors": [
                    "django.template.context_processors.debug",
                    "django.template.context_processors.request",
                    "django.contrib.auth.context_processors.auth",
                    "django.contrib.messages.context_processors.messages",
                    "social_django.context_processors.backends",
                    "social_django.context_processors.login_redirect"
                ],
            },
        },
    ]
    
    REST_FRAMEWORK = {
        "DEFAULT_PERMISSION_CLASSES": {
            "rest_framework.permissions.IsAuthenticated"
        },
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'rest_framework_simplejwt.authentication.JWTAuthentication',
        ),
    }
    
    AUTHENTICATION_BACKENDS = (
        "social_core.backends.google.GoogleOAuth2",  # Enable using google OAuth 2
        "django.contrib.auth.backends.ModelBackend",  # Enable logining via email and password
    )
    
    SIMPLE_JWT = {
        'AUTH_HEADER_TYPES': ('JWT',),
        "ACCESS_TOKEN_LIFETIME": timedelta(days=10000),
        "REFRESH_TOKEN_LIFETIME": timedelta(days=10000),
        "AUTH_TOKEN_CLASSES": (
            "rest_framework_simplejwt.tokens.AccessToken",
        )
    }
    from djoser.social.token.jwt import TokenStrategy
    
    DJOSER = {
        "LOGIN_FIELD": "email",
        "USER_CREATE_PASSWORD_RETYPE": True,  # confirm password field
        "USERNAME_CHANGED_EMAIL_CONFIRMATION": True,  # whenever username is changed - confirmation email is sent
        "PASSWORD_CHANGED_EMAIL_CONFIRMATION": True,
        "SET_USERNAME_RETYPE": True,
        "SET_PASSWORD_RETYPE": True,
        "PASSWORD_RESET_CONFIRM_URL": "password/reset/confirm/{uid}/{token}",
        "USERNAME_RESET_CONFIRM_URL": "email/reset/confirm/{uid}/{token}",
        "ACTIVATION_URL": "activate/{uid}/{token}",  # this should be on frontend, --> auth/users/activation/
        "SEND_ACTIVATION_EMAIL": True,
        "SOCIAL_AUTH_TOKEN_STRATEGY": "djoser.social.token.jwt.TokenStrategy",
        "SOCIAL_AUTH_ALLOWED_REDIRECT_URIS": [
            "http://localhost:8000"
        ],
        "SERIALIZERS": {
            "user_create": "accounts.serializers.UserCreateSerializer",
            "user": "accounts.serializers.UserCreateSerializer",
            "current_user": "accounts.serializers.UserCreateSerializer",
            "user_delete": "djoser.serializers.UserDeleteSerializer",
    
        }
    }
    
    # Google config
    SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = "my_key"
    SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = "my_secret"
    SOCIAL_AUTH_GOOGLE_OAUTH2_SCOPE = [
        "https://www.googleapis.com/auth/userinfo.email",  # retrieve email
        "https://www.googleapis.com/auth/userinfo.profile",
        "openid"
    ]  # when people go to sign up and sing in, they are going to retrieve some data from their accounts
    SOCIAL_AUTH_GOOGLE_OAUTH2_EXTRA_DATA = ["first_name", "last_name"]
    
    AUTH_USER_MODEL = "accounts.UserAccount"
    ...
    

    我发现了很多类似的问题,但是并没有完全解释这个错误的原因是什么。

  • 您遇到的问题是,重定向时状态不是持久的。状态保存在 session key 下 f'_state_{self.name}_{state}' self.name 值并不重要。但一个 state 很重要。 state 在验证您的凭据后重定向时,Google 会将值作为请求参数返回。通常它存储在 oauth_token arg 中。此值与会话或缓存中的值进行比较。

    因此,基本上,您应该 session 在调用后端时保留。如果您使用浏览器,最好使用隐身模式。如果您还想使用邮递员,请确保在发出请求之前将会话复制到请求中。

  • Dewi 3月前 0 只看Ta
    引用 10

    非常感谢!也许这也能帮助到某些人:如果你使用 postman,只需在重定向之前找出 session_id,然后,在使用代码和状态发出 POST 请求时,同时传递“Cookie”标头,其值为“sessionid=在邮递员中

返回
作者最近主题: