Xcode 预览错误 - '@objc' 只能应用于类的扩展

问题描述 投票:0回答:1

我使用的是 Xcode 14.2,其中包含 SwiftUI 文件和 Objective-C 文件,该文件使用

NotificationCenter
更改要显示的文本。有人告诉我,在 iPhone 8 上运行时,我的部分文本被截断,但我无法看到它,因为预览不会显示任何内容,并给出错误说明:

'@objc'只能应用于类的扩展

如何在 iPhone8 上查看此内容,以便修复布局,使所有内容都适合屏幕?

快速代码:

import Foundation
import SwiftUI

@objc public protocol CMWUploadViewV2Delegate: NSObjectProtocol {
    @objc func uploadOKButtonPushed()
    @objc func uploadAbortButtonPushed()
    @objc func uploadErrorLogButtonPushed()
    @objc func uploadRetryButtonPushed()
}

@objc class CMWSTUploadViewV2Controller: UIViewController {
   
    @IBOutlet var ProgressBarView: UIView!
    
    // embed SwiftUI into the UIKit storyboard view controller
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let childView = UIHostingController(rootView: ContentView())
        addChild(childView)
        childView.view.frame = ProgressBarView.bounds
        ProgressBarView.addSubview(childView.view)
        childView.didMove(toParent: self)
        
    }
    
    @objc weak var delegate: CMWUploadViewV2Delegate?
    
    //creating function for dictionary to store changes and create notification
    //This takes a value between 0 and 1 
    @objc func UpdateUploadProgress(progressValue: Float)
    {
        //First, we need to normalize the value which is between 0 and 0.99 to 0 and 0.8999996
        let normalizedValue = progressValue * 0.8999996
        let valueUpdate:[String: Float] = ["ProgressValue": normalizedValue]
        NotificationCenter.default.post(name:NSNotification.Name("COM.CMW.UpdateUploadProgress"), object: nil, userInfo:valueUpdate)
    }
    
    @objc func UpdateInitialText(InitialTextParameter: String)
    {
        let textUpdate:[String: String] = ["InitialTextParameter": InitialTextParameter]
        NotificationCenter.default.post(name:NSNotification.Name("COM.CMW.UpdateInitialText"), object: nil, userInfo:textUpdate)
    }
    
    @objc func UpdateAddressText(AddressTextParameter: String)
    {
        let textUpdate:[String: String] = ["AddressTextParameter": AddressTextParameter]
        NotificationCenter.default.post(name:NSNotification.Name("COM.CMW.UpdateAddressText"), object: nil, userInfo:textUpdate)
    }
    
    @objc func UpdateOrangeText(OrangeTextParameter: String)
    {
        let textUpdate:[String: String] = ["OrangeTextParameter": OrangeTextParameter]
        NotificationCenter.default.post(name:NSNotification.Name("COM.CMW.UpdateOrangeText"), object: nil, userInfo:textUpdate)
    }
    
    @objc func UpdateGreySubText(GreySubTextParameter: String)
    {
        let textUpdate:[String: String] = ["GreySubTextParameter": GreySubTextParameter]
        NotificationCenter.default.post(name:NSNotification.Name("COM.CMW.UpdateGreySubText"), object: nil, userInfo:textUpdate)
    }
    
  
    @objc func UpdateControllerTypeText(ControllerTypeTextParameter: String)
    {
        let textUpdate:[String: String] = ["ControllerTypeTextParameter": ControllerTypeTextParameter]
        NotificationCenter.default.post(name:NSNotification.Name("COM.CMW.UpdateControllerTypeText"), object: nil, userInfo:textUpdate)
    }
    
     @objc func UpdateConnectionTypeText(ConnectionTypeTextParameter: String)
     {
         let textUpdate:[String: String] = ["ConnectionTypeTextParameter": ConnectionTypeTextParameter]
         NotificationCenter.default.post(name:NSNotification.Name("COM.CMW.UpdateConnectionTypeText"), object: nil, userInfo:textUpdate)
     }
    
     @objc func UpdateStatusText(StatusTextParameter: String)
     {
         let textUpdate:[String: String] = ["StatusTextParameter": StatusTextParameter]
         NotificationCenter.default.post(name:NSNotification.Name("COM.CMW.UpdateStatusText"), object: nil, userInfo:textUpdate)
     }
    
    struct ContentView: View {
        //creating vars
        @State var progressValue: Float = 0.3
        //let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
        @State private var degress: Double = -110
        //@State var GreySubText = ""
        let label = UILabel()
        @State var buttonText1 = ""
        @State var buttonText2 = ""
        @State var controllerTypeText = ""
        @State var connectionTypeText = "CAN"
        @State var statusText = "Status text here"
        @State var fourLinesText = "More status text here. Controller responding. This text will be 4 lines in length. 1234567891011121314151617181920. Controller responding. This text will be 4 lines in length. 1234567891011121314151617181920. Controller responding. This text will be 4 lines in length. 1234567891011121314151617181920"
        @State var initialText = "Resetting to upload mode."
        
        //setting up notification center to listen to addresses
        let publisher = NotificationCenter.default.publisher(for: NSNotification.Name("COM.CMW.UpdateUploadProgress"))
        let publisher8 = NotificationCenter.default.publisher(for: NSNotification.Name("COM.CMW.UpdateInitialText"))
        //let publisher6 = NotificationCenter.default.publisher(for: NSNotification.Name("COM.CMW.UpdateAddressText"))
        //let publisher7 = NotificationCenter.default.publisher(for: NSNotification.Name("COM.CMW.UpdateOrangeText"))
        //let publisher5 = NotificationCenter.default.publisher(for: NSNotification.Name("COM.CMW.UpdateGreySubText"))
        let publisher2 = NotificationCenter.default.publisher(for: NSNotification.Name("COM.CMW.UpdateControllerTypeText"))
        let publisher3 = NotificationCenter.default.publisher(for: NSNotification.Name("COM.CMW.UpdateConnectionTypeText"))
        let publisher4 = NotificationCenter.default.publisher(for: NSNotification.Name("COM.CMW.UpdateStatusText"))
        
        //display
        var body: some View {
            VStack {
                Spacer()
                    .frame(height: 70)
                
                if #available(iOS 16.0, *) {
                    Label(initialText, systemImage: "clock")
                        .font(.title)
                        .foregroundColor(Color(hex: "000"))
                        .fontWeight(.bold)
                        .onReceive(publisher8) { obj in
                            let initialTextVal = obj.userInfo?["InitialTextParameter"] as? String
                            initialText = initialTextVal!
                        }

                } else {
                    // Fallback on earlier versions
                    Label(initialText, systemImage: "clock")
                        .font(.title)
                        .foregroundColor(Color(hex: "000"))
                        .onReceive(publisher8) { obj in
                            let initialTextVal = obj.userInfo?["InitialTextParameter"] as? String
                            initialText = initialTextVal!
                        }
                }
                    
                    
                ZStack{
                    //background rectangle
                    RoundedRectangle(cornerRadius: 25)
                        .fill(Color(hex: "494949"))
                        .frame(width: 300, height: 300)
                    
                    ProgressBar(progress: self.$progressValue)
                        .frame(width: 250.0, height: 250.0)
                        .padding(40.0)
                        .onReceive(publisher) { obj in
                            let progVal = obj.userInfo?["ProgressValue"] as? Float
                            progressValue = progVal!
                            }
                    
                    ProgressBarTriangle(progress: self.$progressValue).frame(width: 280.0, height: 290.0).rotationEffect(.degrees(degress), anchor: .bottom)
                        .offset(x: 0, y: -150)
                }
                
                //***Controller, Connection, and Status labels/text
                Spacer()
                    .frame(height: 20)
                VStack(alignment :.leading, spacing: 30) {
                    HStack {
                        if #available(iOS 16.0, *) {
                            Label("Controller type:", image: "ControllerIcon")
                                .foregroundColor(Color(hex: "000"))
                                .fontWeight(.bold)
                        } else {
                            // Fallback on earlier versions
                            Label("Controller type:", image: "ControllerIcon")
                                .foregroundColor(Color(hex: "000"))
                        }
                        Text(controllerTypeText)
                        //app crashes when following code active:
                        //onReceive(publisher2) { obj in
                            //let controllerTextVal = //obj.userInfo?["ControllerTypeTextParameter"] as? String
                            //controllerTypeText = controllerTextVal!
                        //}
                    }
                    
                    HStack {
                        if #available(iOS 16.0, *) {
                            Label("Connection type:", image: "CANIconSmall")
                                .foregroundColor(Color(hex: "000"))
                                .fontWeight(.bold)
                        } else {
                            // Fallback on earlier versions
                            Label("Connection type:", image: "CANIconSmall")
                                .foregroundColor(Color(hex: "000"))
                        }
                        Text(connectionTypeText)
                            .onReceive(publisher3) { obj in
                                let connectionTextVal = obj.userInfo?["ConnectionTypeTextParameter"] as? String
                                connectionTypeText = connectionTextVal!
                            }
                    }
                    
                    HStack {
                        if #available(iOS 16.0, *) {
                            Label("Status:", image: "StatusIcon")
                                .foregroundColor(Color(hex: "000"))
                                .fontWeight(.bold)
                        } else {
                            // Fallback on earlier versions
                            Label("Status:", image: "StatusIcon")
                                .foregroundColor(Color(hex: "000"))
                        }
                        
                    }
                    
                    //four lines of status text
                    Text(fourLinesText)
                        .foregroundColor(Color(hex: "000"))
                        .lineLimit(4)
                        .multilineTextAlignment(.leading)
                        .onReceive(publisher4) { obj in
                            let statusTextVal = obj.userInfo?["StatusTextParameter"] as? String
                            fourLinesText = statusTextVal!
                        }
                    
                    Spacer()
                }
                .padding(.leading, 20)
                .padding(.trailing, 20)
            }
        }
        
        public struct ProgressBar: View {
            //creating vars
            @Binding var progress: Float
            @State var addressText = "0x1c000"
            @State var orangeText = "Orange Text"
            @State var GreySubText = ""
            
            let publisher7 = NotificationCenter.default.publisher(for:
                NSNotification.Name("COM.CMW.UpdateOrangeText"))
            let publisher6 = NotificationCenter.default.publisher(for: NSNotification.Name("COM.CMW.UpdateAddressText"))
            let publisher5 = NotificationCenter.default.publisher(for: NSNotification.Name("COM.CMW.UpdateGreySubText"))
            
            public func UpdateProgressValue(progressValue: Float)
            {
                progress = progressValue
            }
            
            var body: some View {
                
                VStack (alignment :.center, spacing: 30){
                    HStack {
                        Label("Address:", systemImage: "target")
                            .foregroundColor(Color(hex: "8f8f8f"))
                            .padding(.top, 15)
                        Text(addressText)
                            .foregroundColor(Color(hex: "8f8f8f"))
                            .padding(.top, 15)
                            .onReceive(publisher6) { obj in
                                let addressTextVal = obj.userInfo?["AddressTextParameter"] as? String
                                addressText = addressTextVal!
                            }
                    }
                    ZStack {
                        
                        Circle()
                            .trim(from: 0.35, to: 0.85)
                            .stroke(style: StrokeStyle(lineWidth: 12.0, lineCap: .round, lineJoin: .round))
                            .opacity(0.3)
                            .foregroundColor(Color.gray)
                            .rotationEffect(.degrees(54.5))
                        
                        Circle()
                            .trim(from: 0.35, to: CGFloat(self.progress))
                            .stroke(style: StrokeStyle(lineWidth: 12.0, lineCap: .round, lineJoin: .round))
                            .fill(AngularGradient(gradient: Gradient(stops: [
                                .init(color: Color.init(hex: "daff00"), location: 0.39000002),
                                .init(color: Color.init(hex: "00ff04"), location: 0.5999999),
                                .init(color: Color.init(hex: "32E1A0"), location: 0.8099997)]), center: .center))
                            .rotationEffect(.degrees(54.5))
                        
                        VStack(alignment :.center, spacing: 10) {
                            
                            Text("824").font(Font.system(size: 44)).bold().foregroundColor(Color.init(hex: "ffffff"))
                            
                            if #available(iOS 16.0, *) {
                                Label(orangeText, systemImage: "clock")
                                    .foregroundColor(Color(hex: "FF6600"))
                                    .fontWeight(.bold)
                                .onReceive(publisher7) { obj in
                                    let statusTextVal = obj.userInfo?["OrangeTextParameter"] as? String
                                    orangeText = statusTextVal!
                                }
                            } else {
                                // Fallback on earlier versions
                                Label(orangeText, systemImage: "clock")
                                    .foregroundColor(Color(hex: "FF6600"))
                                .onReceive(publisher7) { obj in
                                    let statusTextVal = obj.userInfo?["OrangeTextParameter"] as? String
                                    orangeText = statusTextVal!
                                }
                            }
                            
                            Text(GreySubText)
                                .foregroundColor(Color(hex: "8f8f8f"))
                                .multilineTextAlignment(.center)
                                .onReceive(publisher5) { obj in
                                    let GreySubTextVal = obj.userInfo?["GreySubTextParameter"] as? String
                                    GreySubText = GreySubTextVal!
                                }
                            
                        }
                    }
                    
                }
                
            }
            
        }
        
        struct ProgressBarTriangle: View {
            @Binding var progress: Float
            
            
            var body: some View {
                ZStack {
                    Image("triangle").resizable().frame(width: 10, height: 10, alignment: .center)
                }
            }
        }
    }
    
    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            ContentView()
        }
    }
}
    extension Color {
        init(hex: String) {
            let hex = hex.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
            var int: UInt64 = 0
            Scanner(string: hex).scanHexInt64(&int)
            let a, r, g, b: UInt64
            switch hex.count {
            case 3: // RGB (12-bit)
                (a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
            case 6: // RGB (24-bit)
                (a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF)
            case 8: // ARGB (32-bit)
                (a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
            default:
                (a, r, g, b) = (1, 1, 1, 0)
            }
            
            self.init(
                .sRGB,
                red: Double(r) / 255,
                green: Double(g) / 255,
                blue:  Double(b) / 255,
                opacity: Double(a) / 255
            )
        }
        
    }

目标C代码:

-(void)summerTestUploadViewController
{
    CMWSTUploadViewV2Controller* myView = [[UIStoryboard storyboardWithName:@"MainStoryboard_iPhone" bundle:nil] instantiateViewControllerWithIdentifier:@"ID_CMW_UPLOADVIEWV2_VIEW"];
 //   myView.delegate = self;
    [self presentViewController:myView animated:YES completion:^{
        [myView UpdateUploadProgressWithProgressValue:0.7];
        [myView UpdateInitialTextWithInitialTextParameter:@"Initial text here"];
        [myView UpdateAddressTextWithAddressTextParameter:@"Address text here"];
        [myView UpdateOrangeTextWithOrangeTextParameter:@"Orange text here"];
        [myView UpdateGreySubTextWithGreySubTextParameter:@"Grey sub text here"];
        [myView UpdateControllerTypeTextWithControllerTypeTextParameter:@"Controller text here"];
        [myView UpdateConnectionTypeTextWithConnectionTypeTextParameter:@"Connection text here"];
        [myView UpdateStatusTextWithStatusTextParameter:@"Status text here. 4 lines of text will be allowed in this area.  4 lines of text will be allowed in this area.  4 lines of text will be allowed in this area.  4 lines of text will be allowed in this area.  4 lines of text will be allowed in this area."];
        
    }];
}
xcode swiftui constraints preview xcode14
1个回答
0
投票

要解决 SwiftUI 预览不显示的问题以及 Xcode 14.2 中有关“@objc”的错误消息,并在 iPhone 8 上查看布局以进行调整,以下是您可以执行的操作的摘要:

  1. 修复“@objc”错误:错误消息““@objc”只能应用于类的扩展”表明代码中使用“@objc”属性的方式不匹配。确保它们仅应用于 Objective-C 兼容类的成员或此类类的扩展。

  2. 在 iPhone 8 上预览:

    • 使用 iPhone 8 模拟器:不要依赖 SwiftUI 预览,而是在 iPhone 8 模拟器上运行您的应用程序,以查看它在该特定设备上的外观和行为。这可以通过从模拟器列表中选择 iPhone 8 直接从 Xcode 完成。
    • 调整较小屏幕的布局:如果 iPhone 8 上的文本被截断,则表明您的布局可能无法响应较小的屏幕尺寸。利用 SwiftUI 的自适应布局功能,例如
      GeometryReader
      flexible frames
      ScrollView
      ,使您的 UI 元素动态调整以适应不同的屏幕尺寸。
    • 在模拟器中调试:在模拟器中运行应用程序时使用 Xcode 的调试工具来检查 UI 并确定导致文本被截断的原因。您可以使用断点并查看 UI 层次结构,以更好地了解布局问题。
  3. 一般提示

    • 针对多种设备进行优化:设计您的 SwiftUI 视图,使其灵活并响应不同的屏幕尺寸和方向。这确保了所有设备上一致的用户体验。
    • 定期测试:定期在各种设备和模拟器上测试您的应用程序,以便在开发过程的早期发现并修复布局问题。

通过修复代码中的“@objc”用法并使用 iPhone 8 模拟器测试和调整布局,您应该能够有效解决文本截断问题。请记住定期在不同设备上进行测试,以确保兼容性和良好的用户体验。

让我知道它是否对您有用。 :)

© www.soinside.com 2019 - 2024. All rights reserved.