- エーオーシステム コーポレートサイト
https://www.aosystem.co.jp/ - エーオーシステム プロダクトサイト
https://ao-system.net/ - レンタルサーバー
- バーチャル展示会
- ウェブカタログサービス
- 3Dグラフィック
- Android アプリ
- iOS (iPhone,iPad) アプリ
- Flutter開発
- プログラミング記録QuickAnswer
- 無料画像素材
- スカイボックス 3D SKY BOX
このページのQRコード
下記アプリの主要なソースコードを公開しています。アプリ開発の参考になれば幸いです。
画像等が別途必要ですので下記情報のみでアプリが完成するものではありません。 アプリは少しずつ機能拡張していますのでストア公開されているアプリと内容が異なる場合があります。 コードはコピーして自由にお使いいただけます。ただし著作権は放棄しておりませんので全部の再掲載はご遠慮ください。部分的に再掲載したり、改変して再掲載するのは構いません。 自身のアプリ作成の参考として個人使用・商用問わず自由にお使いいただけます。 コード記述のお手本を示すものではありません。ミニアプリですので変数名などさほど気遣いしていない部分も有りますし間違いも有るかと思いますので参考程度にお考え下さい。 他の賢者の皆様が公開されているコードを参考にした箇所も含まれます。iOSアプリ開発の熟練者が書いたコードではありません。 エンジニア向け技術情報共有サービスではありませんので説明は省いています。ご了承ください。 GitHubなどへの公開は予定しておりません。
//
// ConstValue.swift
// LuckyBox
//
// Created by akira ohmachi on 2021/04/07.
//
import SwiftUI
class ConstValue: ObservableObject {
//background
static let colorBg: Color = Color.init(red:0,green:0.613,blue:0.203)
//button color
static let colorStart: Color = Color.init(red:0.238, green:0.77, blue:0.387)
static let colorSetting: Color = Color.init(red:0.543, green:0.77, blue:0.289)
}
//
// ContentView.swift
// LuckyBox
//
// Created by akira ohmachi on 2021/04/07.
//
import SwiftUI
import GoogleMobileAds
struct ContentView: View {
@EnvironmentObject var pub: PublicManager
@State private var boxImageName: String = "box_001"
private var boxImageNamePrefix: String = "box_"
@State private var timeLine: Int = 0
@State private var busyFlag: Bool = false //実行中
@State private var destroyFlag: Bool = false
@State private var emptyTextAlpha: Double = 0.0
@State private var resultTextName: String = "" //当選名
@State private var resultTextAlpha: Double = 0.0
@State private var resultTextPositionX: CGFloat = 0.45
@State private var resultTextPositionY: CGFloat = 0.66
//PIN input
@State private var isInputPin = false //trueでPIN入力ダイアログが表示される
@State var pin: String = "" //ダイアログで入力したPIN
//
var body: some View {
NavigationView {
GeometryReader { bodyView in
VStack(spacing: 0) {
HStack(spacing: 0) {
Button(action:{
self.startAction()
}){
Text("start")
.frame(width:bodyView.size.width / 4 * 3, height: bodyView.size.height / 6, alignment: .center)
.background(ConstValue.colorStart)
.foregroundColor(Color.white)
}
Rectangle().fill(Color.white).frame(width: 1,height: bodyView.size.height / 6)
NavigationLink(destination: SettingView(),isActive: self.$pub.isSetting) {
Button(action:{
if self.pub.pin == "" {
self.pin = ""
self.buttonActionSetting()
} else {
self.isInputPin = true
}
}){
Text("setting")
.frame(width: bodyView.size.width / 4, height: bodyView.size.height / 6, alignment: .center)
.background(ConstValue.colorSetting)
.foregroundColor(Color.white)
TextFieldAlertView(
text: $pin,
isShowingAlert: $isInputPin,
placeholder: "",
isSecureTextEntry: false,
title: "PIN",
message: "Enter PIN",
leftButtonTitle: "Cancel",
rightButtonTitle: "OK",
leftButtonAction: {
self.pin = ""
},
rightButtonAction: {
self.buttonActionSetting()
}
)
}
}
.background(ConstValue.colorSetting)
}
.frame(width:bodyView.size.width, height:bodyView.size.height / 6)
Rectangle().fill(Color.white).frame(width: bodyView.size.width,height: 1)
ZStack(alignment: .bottom) {
ScrollView {
Text("empty")
.foregroundColor(Color.white)
.opacity(self.emptyTextAlpha)
.padding(10)
Image(self.boxImageName)
.resizable()
.frame(width: bodyView.size.width, height: bodyView.size.width, alignment: .center)
.overlay (
Text(self.resultTextName)
.frame(width:bodyView.size.width, height:bodyView.size.width, alignment: .topLeading)
.foregroundColor(Color.black)
.font(.title2)
.opacity(self.resultTextAlpha)
.offset(CGSize(width: bodyView.size.width * self.resultTextPositionX, height: bodyView.size.width * self.resultTextPositionY))
)
Spacer(minLength: 150)
}
HStack(spacing: 0) {
Spacer(minLength: 0)
PublicManager.AdView().frame(maxWidth: bodyView.size.width, maxHeight: 50)
Spacer(minLength: 0)
}.background(Color(red:0.2,green:0.2,blue:0.2))
}
}
.background(ConstValue.colorBg)
//.navigationBarTitle("")
.navigationBarHidden(true)
}
}
.navigationViewStyle(StackNavigationViewStyle())
.onAppear { //アプリ起動時に実行
self.pub.loadItems()
}
.onChange(of: self.pub.isSetting) { _ in //SettingViewからの戻り
if self.pub.isSetting == false {
self.emptyTextAlpha = 0.0
}
}
.onDisappear { //アプリ終了時
self.destroyFlag = true
}
}
//goto setting
private func buttonActionSetting() {
if self.busyFlag {
return
}
if self.pin != self.pub.pin {
self.pin = ""
return
}
self.emptyTextAlpha = 0.0
self.pin = ""
for i in 0..<self.pub.items.count {
self.pub.tmpItems[i].name = self.pub.items[i].name
self.pub.tmpItems[i].qty = String(self.pub.items[i].qty)
}
self.pub.tmpPin = self.pub.pin
self.pub.isSetting = true
}
//start button on click
private func startAction() {
if self.busyFlag {
return
}
self.busyFlag = true
self.resultTextName = ""
self.resultTextAlpha = 0.0
//textを選ぶ
var alternatives: Array<Int> = []
for i in 0..<self.pub.items.count {
for _ in 0..<self.pub.items[i].qty {
alternatives.append(i)
}
}
if alternatives.count == 0 { //選ぶものが無くなった
self.timeLine = 1
self.setImageName()
self.emptyTextAlpha = 1.0
self.busyFlag = false
return
}
alternatives = alternatives.shuffled() //alternatives[0]に決定
self.resultTextName = self.pub.items[alternatives[0]].name
self.pub.items[alternatives[0]].qty -= 1 //選んだクジを消費する
self.pub.saveItems()
//
self.timeLine = 0
self.timeLineAnimation()
}
//animation
private func timeLineAnimation() {
withAnimation {
if self.destroyFlag {
return
}
self.timeLine += 1
if self.timeLine > 120 {
self.busyFlag = false
return
}
self.setImageName()
self.resultTextDraw()
DispatchQueue.global().async {
Thread.sleep(forTimeInterval: 0.02)
DispatchQueue.main.sync {
if self.destroyFlag == false {
self.timeLineAnimation()
}
}
}
}
}
private func setImageName() {
self.boxImageName = self.boxImageNamePrefix + String(format: "%03d",self.timeLine)
}
private func resultTextDraw() {
let actionStart: Int = 105
if self.timeLine < actionStart {
return
}
let actionSpan: Int = 120 - actionStart
self.resultTextAlpha = Double(actionSpan - (120 - self.timeLine)) / Double(120 - actionStart)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
Group {
ContentView().environmentObject(PublicManager())
}
}
}
//
// LuckyBoxApp.swift
// LuckyBox
//
// Created by akira ohmachi on 2021/04/07.
//
import SwiftUI
import UIKit
import GoogleMobileAds
// AppDelegateクラスを定義する
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
// Mobile Ads SDKを初期化する
GADMobileAds.sharedInstance().start(completionHandler: nil)
return true
}
}
@main
struct LuckyBoxApp: App {
// SwiftUI AppライフサイクルにAppDelegateクラスを注入する
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView().environmentObject(PublicManager())
}
}
}
//
// PublicManager.swift
// LuckyBox
//
// Created by akira ohmachi on 2021/04/07.
//
import SwiftUI
import GoogleMobileAds
class PublicManager: ObservableObject {
@Published var isSetting: Bool = false
@AppStorage("item1name") var item1name: String = ""
@AppStorage("item2name") var item2name: String = ""
@AppStorage("item3name") var item3name: String = ""
@AppStorage("item4name") var item4name: String = ""
@AppStorage("item5name") var item5name: String = ""
@AppStorage("item6name") var item6name: String = ""
@AppStorage("item7name") var item7name: String = ""
@AppStorage("item8name") var item8name: String = ""
@AppStorage("item9name") var item9name: String = ""
@AppStorage("item10name") var item10name: String = ""
@AppStorage("item1qty") var item1qty: Int = 0
@AppStorage("item2qty") var item2qty: Int = 0
@AppStorage("item3qty") var item3qty: Int = 0
@AppStorage("item4qty") var item4qty: Int = 0
@AppStorage("item5qty") var item5qty: Int = 0
@AppStorage("item6qty") var item6qty: Int = 0
@AppStorage("item7qty") var item7qty: Int = 0
@AppStorage("item8qty") var item8qty: Int = 0
@AppStorage("item9qty") var item9qty: Int = 0
@AppStorage("item10qty") var item10qty: Int = 0
@AppStorage("pin") var pin: String = ""
@Published var tmpPin: String = ""
struct Item {
var name: String
var qty: Int
init(name: String, qty: Int) {
self.name = name
self.qty = qty
}
}
var items: Array<Item> = [
Item(name: "", qty: 0),
Item(name: "", qty: 0),
Item(name: "", qty: 0),
Item(name: "", qty: 0),
Item(name: "", qty: 0),
Item(name: "", qty: 0),
Item(name: "", qty: 0),
Item(name: "", qty: 0),
Item(name: "", qty: 0),
Item(name: "", qty: 0),
]
struct TmpItem {
var name: String
var qty: String
init(name: String, qty: String) {
self.name = name
self.qty = qty
}
}
var tmpItems: Array<TmpItem> = [
TmpItem(name: "", qty: ""),
TmpItem(name: "", qty: ""),
TmpItem(name: "", qty: ""),
TmpItem(name: "", qty: ""),
TmpItem(name: "", qty: ""),
TmpItem(name: "", qty: ""),
TmpItem(name: "", qty: ""),
TmpItem(name: "", qty: ""),
TmpItem(name: "", qty: ""),
TmpItem(name: "", qty: ""),
]
func saveItems() {
self.item1name = self.items[0].name
self.item1qty = self.items[0].qty
self.item2name = self.items[1].name
self.item2qty = self.items[1].qty
self.item3name = self.items[2].name
self.item3qty = self.items[2].qty
self.item4name = self.items[3].name
self.item4qty = self.items[3].qty
self.item5name = self.items[4].name
self.item5qty = self.items[4].qty
self.item6name = self.items[5].name
self.item6qty = self.items[5].qty
self.item7name = self.items[6].name
self.item7qty = self.items[6].qty
self.item8name = self.items[7].name
self.item8qty = self.items[7].qty
self.item9name = self.items[8].name
self.item9qty = self.items[8].qty
self.item10name = self.items[9].name
self.item10qty = self.items[9].qty
}
func loadItems() {
self.items[0].name = self.item1name
self.items[0].qty = self.item1qty
self.items[1].name = self.item2name
self.items[1].qty = self.item2qty
self.items[2].name = self.item3name
self.items[2].qty = self.item3qty
self.items[3].name = self.item4name
self.items[3].qty = self.item4qty
self.items[4].name = self.item5name
self.items[4].qty = self.item5qty
self.items[5].name = self.item6name
self.items[5].qty = self.item6qty
self.items[6].name = self.item7name
self.items[6].qty = self.item7qty
self.items[7].name = self.item8name
self.items[7].qty = self.item8qty
self.items[8].name = self.item9name
self.items[8].qty = self.item9qty
self.items[9].name = self.item10name
self.items[9].qty = self.item10qty
var empty: Bool = true
for i in 0..<items.count {
if self.items[i].name != "" {
empty = false
break
}
}
if empty {
self.items[0].name = NSLocalizedString("rank1", comment: "rank1")
self.items[0].qty = 1
self.items[1].name = NSLocalizedString("rank2", comment: "rank2")
self.items[1].qty = 3
self.items[2].name = NSLocalizedString("rank3", comment: "rank3")
self.items[2].qty = 5
self.items[3].name = NSLocalizedString("rank4", comment: "rank4")
self.items[3].qty = 10
self.items[4].name = NSLocalizedString("rank5", comment: "rank5")
self.items[4].qty = 20
self.items[5].name = NSLocalizedString("rank6", comment: "rank6")
self.items[5].qty = 20
self.items[6].name = NSLocalizedString("rank7", comment: "rank7")
self.items[6].qty = 30
self.saveItems()
}
}
//--------------------------------------------------
//adMob
struct AdView: UIViewRepresentable {
func makeUIView(context: Context) -> GADBannerView {
let banner = GADBannerView(adSize: kGADAdSizeBanner)
#if DEBUG
banner.adUnitID = "ca-app-pub-3940256099942544/2934735716"
#else
banner.adUnitID = "ca-app-pub-0000000000000000/0000000000"
#endif
banner.rootViewController = UIApplication.shared.windows.first?.rootViewController
banner.load(GADRequest())
return banner
}
func updateUIView(_ uiView: GADBannerView, context: Context) {
}
}
//--------------------------------------------------
}
//
// SettingView.swift
// LuckyBox
//
// Created by akira ohmachi on 2021/04/07.
//
import SwiftUI
struct SettingView: View {
@EnvironmentObject var pub: PublicManager
let inputNameWidth: CGFloat = 0.55
//init() {
// UITableView.appearance().sectionHeaderHeight = .zero
// UITableView.appearance().sectionFooterHeight = 10
//}
var body: some View {
VStack(spacing: 0) {
HStack(spacing: 0) {
Button(action: {
self.pub.isSetting = false
}) {
HStack {
Image(systemName: "arrow.backward")
Text("cancel")
}
}
Spacer()
Button(action: {
for i in 0..<self.pub.items.count {
self.pub.items[i].name = self.pub.tmpItems[i].name
self.pub.items[i].qty = self.adjustStrToNum(str: self.pub.tmpItems[i].qty)
}
self.pub.saveItems()
self.pub.loadItems()
self.pub.pin = self.pub.tmpPin
self.pub.isSetting = false
}) {
HStack {
Text("apply")
Image(systemName: "checkmark.circle")
}
}
}
.padding(20)
}
GeometryReader { bodyView in
Form {
Section(header: Text("ticket name / quantity")) {
VStack {
ForEach(0..<self.pub.items.count) { num in
HStack {
Text("\(String(format: "%02d",num + 1))").font(.caption2)
TextField("", text: self.$pub.tmpItems[num].name)
.textFieldStyle(RoundedBorderTextFieldStyle())
.frame(minWidth: bodyView.size.width * self.inputNameWidth)
TextField("", text: Binding(
get: {self.pub.tmpItems[num].qty},
set: {self.pub.tmpItems[num].qty = $0.filter{"0123456789".contains($0)}}))
.textFieldStyle(RoundedBorderTextFieldStyle())
.keyboardType(.numberPad)
}
}
}
}
Section(header: Text("pin")) {
HStack {
Text("pin")
TextField("", text: Binding(
get: {self.pub.tmpPin},
set: {self.pub.tmpPin = $0.filter{"0123456789".contains($0)}}))
.textFieldStyle(RoundedBorderTextFieldStyle())
.keyboardType(.numberPad)
}
Text("pin1")
.font(.footnote)
Text("pin2")
.font(.footnote)
}
Section(header: Text("usage")) {
Text("usage1")
.font(.footnote)
}
}
}
//.navigationBarTitle("Setting",displayMode: .automatic)
//.navigationViewStyle(StackNavigationViewStyle())
.navigationBarHidden(true)
.onTapGesture { //背景タップでキーボードを閉じる
UIApplication.shared.closeKeyboard()
}
}
func adjustStrToNum(str: String) -> Int {
return NumberFormatter().number(from: "0" + str) as! Int
}
}
extension UIApplication {
func closeKeyboard() { //キーボードを閉じる
sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
}
struct SettingView_Previews: PreviewProvider {
static var previews: some View {
Group {
SettingView().environmentObject(PublicManager())
}
}
}
//
// TextFieldAlertView.swift
// LuckyBox
//
// Created by akira ohmachi on 2021/04/08.
//
import SwiftUI
struct TextFieldAlertView: UIViewControllerRepresentable {
@Binding var text: String
@Binding var isShowingAlert: Bool
let placeholder: String
let isSecureTextEntry: Bool
let title: String
let message: String
let leftButtonTitle: String?
let rightButtonTitle: String?
var leftButtonAction: (() -> Void)?
var rightButtonAction: (() -> Void)?
func makeUIViewController(context: UIViewControllerRepresentableContext<TextFieldAlertView>) -> some UIViewController {
return UIViewController()
}
func updateUIViewController(_ uiViewController: UIViewControllerType, context: UIViewControllerRepresentableContext<TextFieldAlertView>) {
guard context.coordinator.alert == nil else {
return
}
if !isShowingAlert {
return
}
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
context.coordinator.alert = alert
alert.addTextField { textField in
textField.placeholder = placeholder
textField.text = text
textField.delegate = context.coordinator
textField.isSecureTextEntry = isSecureTextEntry
}
if leftButtonTitle != nil {
alert.addAction(UIAlertAction(title: leftButtonTitle, style: .default) { _ in
alert.dismiss(animated: true) {
isShowingAlert = false
leftButtonAction?()
}
})
}
if rightButtonTitle != nil {
alert.addAction(UIAlertAction(title: rightButtonTitle, style: .default) { _ in
if let textField = alert.textFields?.first, let text = textField.text {
self.text = text
}
alert.dismiss(animated: true) {
isShowingAlert = false
rightButtonAction?()
}
})
}
DispatchQueue.main.async {
uiViewController.present(alert, animated: true, completion: {
isShowingAlert = false
context.coordinator.alert = nil
})
}
}
func makeCoordinator() -> TextFieldAlertView.Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, UITextFieldDelegate {
var alert: UIAlertController?
var view: TextFieldAlertView
init(_ view: TextFieldAlertView) {
self.view = view
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if let text = textField.text as NSString? {
self.view.text = text.replacingCharacters(in: range, with: string)
} else {
self.view.text = ""
}
return true
}
}
}
このページのQRコード
便利ウェブサイト
便利 Android アプリ
便利 iOS(iPhone,iPad) アプリ