magukappu
@magukappu (yama)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

電卓に履歴機能を追加したい

解決したいこと

あるお方の動画を見ながら電卓のコードを書いたのですが、ボタンを押したら計算した履歴が画面遷移して見れるようにしたいのですがやり方がわかりません。どなたか教えてください。
押すボタンはlogと書かれたボタンにしてください
移動先のファイル名はLogViewにしてくだい

ソースコード

import SwiftUI

enum CaluculateState {
    case initial, addition, substraction, division, multiplication, sum
}

struct ContentView: View {
    @State var selectedItem: String = "0"
    @State var caluculatedNumber: Double = 0
    @State var caluculateState: CaluculateState = .initial
    
    private let caluculateItems: [[String]] = [
        ["AC", "list", "log", "count"],
        ["7", "8", "9", "÷"],
        ["4", "5", "6", "X"],
        ["1", "2", "3", "-"],
        ["0", ".", "=", "+"],
    ]
    
    var body: some View {
        
        ZStack {
            
            Color.black
                .ignoresSafeArea()
            
            VStack {
                
                Spacer()
                
                HStack {
                    Spacer()
                    
                    Text(selectedItem == "0" ? checkDecimal(number: caluculatedNumber) : selectedItem)
                        .font(.system(size: 100, weight: .light))
                        .foregroundColor(Color.white)
                        .padding()
                        .lineLimit(1)
                        .minimumScaleFactor(0.4)
                }
                
                VStack {
                    ForEach(caluculateItems, id: \.self) { items in
                        NumberView(selectedItem: $selectedItem,
                                   caluculatedNumber: $caluculatedNumber,
                                   caluculateState: $caluculateState,
                                   items: items)
                    }
                }
            }
            .padding(.bottom, 40)
        }
    }
    
    
    private func checkDecimal(number: Double) -> String {
        if number.truncatingRemainder(dividingBy: 1).isLess(than: .ulpOfOne) {
            return String(Int(number))
        } else {
            return String(number)
        }
    }
    
}

struct NumberView: View {
    @State var CmView = false
    @State var LOGView = false
    @State var LISTView = false
    @Binding var selectedItem: String
    @Binding var caluculatedNumber: Double
    @Binding var caluculateState: CaluculateState

    var items: [String]
    
    private let buttonWidth: CGFloat = (UIScreen.main.bounds.width - 50) / 4
    private let numbers: [String] = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "."]
    private let symbols: [String] = ["÷", "X", "-", "+", "="]
        
    
    var body: some View {
        
        HStack {
            
            ForEach(items, id: \.self) { item in
                
                Button {
                    handleButtonInfo(item: item)
                } label: {
                    Text(item)
                        .font(.system(size: 30, weight: .regular))
                        .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
                }
                .foregroundColor(numbers.contains(item) || symbols.contains(item) ? .white : .black)
                .background(handleButtonColor(item: item))
               .sheet(isPresented: $LOGView) {
                   LogView()
               }
               .sheet(isPresented: $CmView) {
                   CMView()
               }
               .sheet(isPresented: $LISTView) {
                   ListView()
               }
                .cornerRadius(buttonWidth)

            }
            .frame(height: buttonWidth)
        }
    }
    
    
    private func handleButtonColor(item: String) -> Color {
        if numbers.contains(item) {
            return Color(white: 0.2, opacity: 1)
        } else if symbols.contains(item) {
            return Color.orange
        } else {
            return Color(white: 0.8, opacity: 1)
        }
    }
    
    
    private func handleButtonInfo(item: String) {
        
        
        if numbers.contains(item) {
           
            if item == "." && (selectedItem.contains(".") || selectedItem.contains("0")) {
                return
            }
            
            
            if selectedItem.count >= 10 {
                return
            }
            
            
            if selectedItem == "0" {
                selectedItem = item
                return
            }
            
            selectedItem += item
        } else if item == "AC" {
            selectedItem = "0"
            caluculatedNumber = 0
            caluculateState = .initial
        }else if item == "log" {
            LOGView = true
        }else if item == "list" {
            LISTView = true
        }else if item == "count" {
            CmView = true
        }
        
        guard let selectedNumber = Double(selectedItem) else { return }
        
        if item == "÷" {
            setCaluculate(state: .division, selectedNumber: selectedNumber)
        } else if item == "X" {
            setCaluculate(state: .multiplication, selectedNumber: selectedNumber)
        } else if item == "-" {
            setCaluculate(state: .substraction, selectedNumber: selectedNumber)
        } else if item == "+" {
            setCaluculate(state: .addition, selectedNumber: selectedNumber)
        } else if item == "=" {
            selectedItem = "0"
            caluculate(selectedNumber: selectedNumber)
            caluculateState = .sum
        }
    }
    
    
    private func setCaluculate(state: CaluculateState, selectedNumber: Double) {
        if selectedItem == "0" {
            caluculateState = state
            return
        }
        
        selectedItem = "0"
        caluculateState = state
        caluculate(selectedNumber: selectedNumber)
    }
    
    
    private func caluculate(selectedNumber: Double) {
        
        if caluculatedNumber == 0 {
            caluculatedNumber = selectedNumber
            return
        }
        
        switch caluculateState {
        case .addition:
            caluculatedNumber = caluculatedNumber + selectedNumber
        case .substraction:
            caluculatedNumber = caluculatedNumber - selectedNumber
        case .division:
            caluculatedNumber = caluculatedNumber / selectedNumber
        case .multiplication:
            caluculatedNumber = caluculatedNumber * selectedNumber
        default:
            break
        }
        
    }
    
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}


解決したコード↓





import SwiftUI
import CoreData

enum CaluculateState {
    case initial, addition, substraction, division, multiplication, sum
}

struct ContentView: View {
    @State var selectedItem: String = "0"
    @State var caluculatedNumber: Double = 0
    @State var caluculateState: CaluculateState = .initial
    
    
    private let caluculateItems: [[String]] = [
        ["count", "list", "log", "AC"],
        ["7", "8", "9", "÷"],
        ["4", "5", "6", "X"],
        ["1", "2", "3", "-"],
        ["0", ".", "=", "+"],
    ]

    var body: some View {

        ZStack {

            Color.black
                .ignoresSafeArea()

            VStack {

                Spacer()

                HStack {
                    Spacer()

                    Text(selectedItem == "0" ? checkDecimal(number: caluculatedNumber) : selectedItem)
                        .font(.system(size: 100, weight: .light))
                        .foregroundColor(Color.white)
                        .padding()
                        .lineLimit(1)
                        .minimumScaleFactor(0.4)
                }

                VStack {
                    ForEach(caluculateItems, id: \.self) { items in
                        NumberView(selectedItem: $selectedItem,
                                   caluculatedNumber: $caluculatedNumber,
                                   caluculateState: $caluculateState,
                                   items: items)
                    }
                }
            }
            .padding(.bottom, 40)
        }
    }


    private func checkDecimal(number: Double) -> String {
        if number.truncatingRemainder(dividingBy: 1).isLess(than: .ulpOfOne) {
            return String(Int(number))
        } else {
            return String(number)
        }
    }

}

struct NumberView: View {
    @State var CmView = false
    @State var LOGView = false
    @State var LISTView = false
    @Binding var selectedItem: String
    @Binding var caluculatedNumber: Double
    @Binding var caluculateState: CaluculateState
    @Environment(\.managedObjectContext) private var context
    @FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \LogsData.answer, ascending: true)],animation: .default) var Data: FetchedResults<LogsData>
    
    var items: [String]

    private let buttonWidth: CGFloat = (UIScreen.main.bounds.width - 50) / 4
    private let numbers: [String] = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "."]
    private let symbols: [String] = ["÷", "X", "-", "+", "="]
    
    
    

    var body: some View {

        HStack {

            ForEach(items, id: \.self) { item in

                Button {
                    handleButtonInfo(item: item)
                } label: {
                    Text(item)
                        .font(.system(size: 30, weight: .regular))
                        .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
                }
                .foregroundColor(numbers.contains(item) || symbols.contains(item) ? .white : .black)
                .background(handleButtonColor(item: item))
               .sheet(isPresented: $LOGView) {
                   LogView()
               }
               .sheet(isPresented: $CmView) {
                   CMView()
               }
               .sheet(isPresented: $LISTView) {
                   ListView()
               }
                .cornerRadius(buttonWidth)

            }
            .frame(height: buttonWidth)
        }
    }


    private func handleButtonColor(item: String) -> Color {
        if numbers.contains(item) {
            return Color(white: 0.2, opacity: 1)
        } else if symbols.contains(item) {
            return Color.orange
        } else {
            return Color(white: 0.8, opacity: 1)
        }
    }


    private func handleButtonInfo(item: String) {


        if numbers.contains(item) {

            if item == "." && (selectedItem.contains(".") || selectedItem.contains("0")) {
                return
            }


            if selectedItem.count >= 10 {
                return
            }


            if selectedItem == "0" {
                selectedItem = item
                return
            }

            selectedItem += item
        } else if item == "AC" {
            selectedItem = "0"
            caluculatedNumber = 0
            caluculateState = .initial
        }else if item == "log" {
            LOGView = true
        }else if item == "list" {
            LISTView = true
        }else if item == "count" {
            CmView = true
        }

        guard let selectedNumber = Double(selectedItem) else { return }

        if item == "÷" {
            setCaluculate(state: .division, selectedNumber: selectedNumber)
        } else if item == "X" {
            setCaluculate(state: .multiplication, selectedNumber: selectedNumber)
        } else if item == "-" {
            setCaluculate(state: .substraction, selectedNumber: selectedNumber)
        } else if item == "+" {
            setCaluculate(state: .addition, selectedNumber: selectedNumber)
        } else if item == "=" {
            selectedItem = "0"
            caluculate(selectedNumber: selectedNumber)
            caluculateState = .sum
        }
    }


    private func setCaluculate(state: CaluculateState, selectedNumber: Double) {
        if selectedItem == "0" {
            caluculateState = state
            return
        }

        selectedItem = "0"
        caluculateState = state
        caluculate(selectedNumber: selectedNumber)
    }
    private func save() {

    }
    
    
    
    private func caluculate(selectedNumber: Double) {

        let FN = caluculatedNumber
        
        if caluculatedNumber == 0 {
            caluculatedNumber = selectedNumber
            return
        }
        
        switch caluculateState {
        case .addition:
            
            caluculatedNumber = caluculatedNumber + selectedNumber

            let t = LogsData(context: context)
            t.answer = String("\(FN)+\(selectedNumber)=\(caluculatedNumber)")
            do {
                try context.save()
            } catch {
           
            }
            
        case .substraction:
            caluculatedNumber = caluculatedNumber - selectedNumber
            
            let t = LogsData(context: context)
            t.answer = String("\(selectedItem)-\(setCaluculate)=\(caluculatedNumber)")
            do {
                try context.save()
            } catch {
                
            }
            
        case .division:
            caluculatedNumber = caluculatedNumber / selectedNumber
            
            let t = LogsData(context: context)
            t.answer = String("\(selectedItem)÷\(setCaluculate)=\(caluculatedNumber)")
            do {
                try context.save()
            } catch {
                
            }
            
        case .multiplication:
            caluculatedNumber = caluculatedNumber * selectedNumber
           
            let t = LogsData(context: context)
            t.answer = String("\(selectedItem)X\(setCaluculate)=\(caluculatedNumber)")
            do {
                try context.save()
            } catch {
                
            }
            
        default:
            break
        }

    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}


参考になったサイト・動画

0

No Answers yet.

Your answer might help someone💌