Platforms to show: All Mac Windows Linux Cross-Platform

/MacCloud/Store Kit Test/Subscription with MBS


Last modified Tue, 10th Mar 2025.

You find this example project in your MBS Xojo Plugin download as a Xojo project file within the examples folder: /MacCloud/Store Kit Test/Subscription with MBS

Download this example: Subscription with MBS.zip

Project "Subscription with MBS.xojo_binary_project"
Class App Inherits MobileApplication
Const useSentry = False
EventHandler Sub Opening() //Do some initialization AppStoreModule.Init call AppStoreModule.CheckSubscriptions //RevenueCat is optional but highly recommended to manage users and subscriptions Dim rvc As new RevenueCat rvc.Init End EventHandler
Note "ABOUT"
Written by Jeremie Leroy https://forum.xojo.com/u/jeremie_l/summary
End Class
Class Screen1 Inherits MobileScreen
Control Button1 Inherits MobileButton
ControlInstance Button1 Inherits MobileButton
Constraint Constraint 1
Constraint Constraint 2
Constraint Constraint 3
Constraint Constraint 4
EventHandler Sub Pressed() Dim v As new vIAPVertical v.ShowModal(self) End EventHandler
End Control
Control Button2 Inherits MobileButton
ControlInstance Button2 Inherits MobileButton
Constraint Constraint 1
Constraint Constraint 2
Constraint Constraint 3
Constraint Constraint 4
EventHandler Sub Pressed() Dim result() as String result = AppStoreModule.CheckSubscriptions if result.Count > 0 then MessageBox(result(0) + " is an active subscription") Else MessageBox("No subscription is currently active") end if End EventHandler
End Control
Control Label1 Inherits MobileLabel
ControlInstance Label1 Inherits MobileLabel
Constraint Constraint 1
Constraint Constraint 2
Constraint Constraint 3
Constraint Constraint 4
End Control
End Class
Class LaunchScreen Inherits MobileScreen
End Class
Sign
End Sign
Sign
End Sign
Class myPaymentQueue Inherits SKPaymentQueueMBS
Delegate Sub RestoreFailedDelegate(Error as NSErrorMBS)
Delegate Sub UpdatedTransactionsDelegate(transactions() as SKPaymentTransactionMBS)
Event restoreCompletedTransactionsFailedWithError(Error as NSErrorMBS) End Event
Event updatedTransactions(transactions() as SKPaymentTransactionMBS) End Event
EventHandler Sub restoreCompletedTransactionsFailedWithError(Error as NSErrorMBS) 'MessageBox "Restoring completed transactions failed with Error: "+Error.localizedDescription call AppStoreModule.CheckSubscriptions RaiseEvent restoreCompletedTransactionsFailedWithError(Error) if RestoreFailedCallback <> nil then RestoreFailedCallback.Invoke(Error) end if End EventHandler
EventHandler Sub updatedTransactions(transactions() as SKPaymentTransactionMBS) #if DebugBuild System.DebugLog CurrentMethodName #endif // Implement the updatedTransactions method // The observer’s updatedTransactions method is called whenever new transactions are created or updated. for each transaction as SKPaymentTransactionMBS in transactions Select case transaction.transactionState case SKPaymentTransactionMBS.StatePurchased #if app.useSentry app.sentry.AddExtraKeyValue("transactionState", "Purchased") #endif completeTransaction Transaction case SKPaymentTransactionMBS.StateFailed #if app.useSentry app.sentry.AddExtraKeyValue("transactionState", "Failed") #endif failedTransaction transaction case SKPaymentTransactionMBS.StateRestored #if app.useSentry app.sentry.AddExtraKeyValue("transactionState", "Restored") #endif restoreTransaction transaction end Select next RaiseEvent updatedTransactions(transactions) if UpdatedTransactionsCallback <> nil then UpdatedTransactionsCallback.Invoke(transactions) end if call AppStoreModule.CheckSubscriptions #if app.useSentry app.sentry.RemoveExtraKeyValue("transactionState") #endif End EventHandler
Sub completeTransaction(transaction as SKPaymentTransactionMBS) System.DebugLog CurrentMethodName // Your observer provides the product when the user successfully purchases an item. #if DebugBuild MessageBox "Transaction is now complete"+EndOfLine+EndOfLine+Transaction.payment.productIdentifier #endif // todo recordTransaction transaction provideContent transaction.payment.productIdentifier // Remove the transaction from the payment queue. self.finishTransaction Transaction // A successful transaction includes a transactionIdentifier property and a transactionReceipt // property that record the details of the processed payment. Your application is not required // to do anything with this information. You may wish to record this information to establish // an audit trail for the transaction. If your application uses a server to deliver content, // the receipt can be sent to your server and validated by the App Store. // It is critical that your application take whatever steps are necessary to provide the // product that the user purchased. Payment has already been collected, so the user expects // to receive the new purchase. See “Feature Delivery” for suggestions on how you might implement this. // Once you’ve delivered the product, your application must call finishTransaction // to complete the transaction. When you call finishTransaction, the transaction // is removed from the payment queue. To ensure that products are not lost, your // application should deliver the product before calling finishTransaction. End Sub
Sub failedTransaction(transaction as SKPaymentTransactionMBS) System.DebugLog CurrentMethodName // Finish the transaction for a failed purchase. if transaction.error.code <> StoreKitMBS.SKErrorPaymentCancelled then // Optionally, display an error here. 'MessageBox "Transaction is failed."+EndOfLine+EndOfLine+Transaction.error.localizedDescription end if self.finishTransaction Transaction // Usually a transaction fails because the user decided not to purchase the item. // Your application can read the error field on a failed transaction to learn // exactly why the transaction failed. // The only requirement for a failed purchase is that your application remove // it from the queue. If your application chooses to put up an dialog displaying // the error to the user, you should avoid presenting an error when the user // cancels a purchase. End Sub
Sub provideContent(identifier as string) #if DebugBuild System.DebugLog CurrentMethodName #endif 'MessageBox "Provide Content for "+identifier //Save the identifier in NSUserDefaults NSUserDefaults.SetBoolForKey(True, identifier) dim userInfo as new Dictionary userInfo.Value("productID") = identifier Notification_Center.JK_NotificationCenter.MainCenter.PostNotification(_ new Notification_Center.JK_Notification(AppStoreModule.SKProvideContentForProductNotification, self, userInfo)) End Sub
Sub recordTransaction(Transaction as SKPaymentTransactionMBS) //This method can be ignored if you do not need to send the successful payment to your database if Transaction is nil then Return Dim transactionDate As DateTime Dim price As String Dim success As Boolean Dim identifier As String = transaction.transactionIdentifier transactionDate = Transaction.transactionDateTime Dim productID As String Dim quantity As Integer Dim appUserName As String dim payment as SKPaymentMBS = Transaction.payment if payment <> nil then productID = payment.productIdentifier quantity = payment.quantity appUserName = payment.applicationUsername Else productID = "Payment is nil" end if Dim state As String Dim restored As Boolean Select case transaction.transactionState case SKPaymentTransactionMBS.StatePurchased state = "Purchased" success = True if AppStoreModule.firstPurchase is nil then AppStoreModule.firstPurchase = DateTime.Now end if case SKPaymentTransactionMBS.StateFailed state = "Failed" case SKPaymentTransactionMBS.StateRestored state = "Restored" restored = True case SKPaymentTransactionMBS.StateDeferred state = "Deferred" else state = "unknown state" end Select //This is where you can record the transaction in an online database #if False Dim js As new Dictionary try js.Value("transactionID") = identifier if transactionDate <> Nil Then js.Value("transactionDate") = transactionDate.SQLDateTime end if js.Value("productID") = productID js.Value("quantity") = quantity js.Value("appUsername") = appUserName js.Value("origin") = "iOS" js.Value("store") = "AppStore" js.Value("state") = state if productID.Contains("yearly") or productID.Contains("monthly") or productID.Contains("subscription") then js.Value("subscription") = 1 Else js.Value("subscription") = 0 end if 'js.Value("userID") = Session.userID js.Value("user_uuid") = Globals.user_uuid 'js.Value("internalProduct") = "" js.Value("purchase_uuid") = Module1.RandomUUID Dim hValue As String Select case AppStoreModule.highlight case cIAPController.Highlights.None hValue = "none" case cIAPController.Highlights.Ads hValue = "ads" case cIAPController.Highlights.categories hValue = "categories" case cIAPController.Highlights.quotes hValue = "quotes" case cIAPController.Highlights.reminders hValue = "reminders" case cIAPController.Highlights.themes hValue = "themes" Else Break End Select js.Value("internalProduct") = hValue //Find the product Dim purchasedProduct As SKProductMBS if AppStoreModule.ProductRequest <> nil then for each p as SKProductMBS in AppStoreModule.ProductRequest.validProducts if p.productIdentifier = productID then purchasedProduct = p exit end if next if purchasedProduct <> nil then js.Value("price") = purchasedProduct.price js.Value("locale") = purchasedProduct.priceLocale.Identifier js.Value("currencySymbol") = purchasedProduct.priceLocale.CurrencySymbol try price = purchasedProduct.price.ToString(locale.Current, "0.00") + " " + purchasedProduct.priceLocale.Identifier.Right(3) Catch End Try end if end if //And finally send the json to your database Globals.OnlineDatabase.PostJS("purchases", js) Catch err #if app.useSentry app.sentry.AddExtraKeyValue("js", GenerateJSON(js)) app.sentry.SubmitException(err, CurrentMethodName + "_err") #endif end try #endif if success then //Do something special on success End If Exception err #if app.useSentry app.sentry.SubmitException(err, CurrentMethodName) #endif End Sub
Sub restoreTransaction(transaction as SKPaymentTransactionMBS) // Finish the transaction for a restored purchase. System.DebugLog CurrentMethodName recordTransaction transaction if transaction.originalTransaction <> nil and transaction.originalTransaction.payment <> nil then provideContent transaction.originalTransaction.payment.productIdentifier end if self.finishTransaction transaction 'AppStoreModule.PaymentQueue.finishTransaction Transaction // This routine is similar to that for a purchased item. // A restored purchase provides a new transaction, including a different transaction // identifier and receipt. You can save this information separately as part of any // audit trail if you desire. However, when it comes time to complete the transaction, // you’ll want to recover the original transaction that holds the actual payment object // and use its product identifier. End Sub
Property RestoreFailedCallback As RestoreFailedDelegate
Property UpdatedTransactionsCallback As UpdatedTransactionsDelegate
End Class
Module AppStoreModule
ComputedProperty Protected firstPurchase As DateTime
Sub Set() NSUserDefaults.SetTextForKey(value.sqldatetime, "firstPurchase") End Set
Sub Get() Try Dim t As String = NSUserDefaults.TextForKey("firstPurchase") If t.isEmpty = False Then Dim d As DateTime = DateTime.FromString(t) Return d End If Catch End Try End Get
End ComputedProperty
Const SKProvideContentForProductNotification = skprovidecontent
Const kIAPPrefix = ""
Const localAnnualy = "Annually"
Const localBestDeal = "Best deal"
Const localCancelAnytime = "Cancel anytime"
Const localContinue = "Continue "
Const localFamilySharing = "Purchase can be shared with family group."
Const localLifetime = "Lifetime"
Const localMonthly = "Monthly "
Const localMostPopular = "Most popular"
Const localPerMonth = "per month"
Const localPerYear = "per year"
Const localPricePerMonth = "2.99 / month"
Const localPricePerYear = "2.99 / year"
Const localPrivacyPolicy = "Privacy policy"
Const localRestore = Already purchased? Restore
Const localSavePercent = "Save %1"
Const localTermsOfUse = "Terms of use"
Const localTotalReviews = "Based on over 2,000 reviews"
Protected Function CheckPurchase(ID as string) As boolean var receipt as AppReceiptMBS Receipt = AppReceiptMBS.bundleReceipt if receipt=nil then return false var ar() as AppReceiptIAPMBS = receipt.inAppPurchases for i as integer= 0 to ar.LastIndex if ar(i).productIdentifier = id then if ar(i).cancellationDateTime = nil then return true end if end if next i return false End Function
Protected Function CheckSubscriptions() As String() #if not DebugBuild #Pragma Error "Need to change subscription identifiers" #endif //Add all identifiers for your subscriptions subscriptionIDs.Add "<<app.premium.month.3" subscriptionIDs.Add "<<app.premium.year.10" subscriptions.removeall var receipt as AppReceiptMBS Receipt = AppReceiptMBS.bundleReceipt var active() as String if receipt = nil then return active var ar() as AppReceiptIAPMBS = receipt.inAppPurchases var dt as datetime = datetime.now for each identifier as String in subscriptionIDs identifier = identifier.Lowercase.Trim var valid as boolean for i as integer = 0 to ar.LastIndex if ar(i).productIdentifier.Lowercase.Trim <> identifier then continue if ar(i).subscriptionExpirationDateTime = nil then subscriptions.AddRow ar(i) active.Add ar(i).productIdentifier exit end if if ar(i).isActiveAutoRenewableSubscriptionForDate( dt ) then subscriptions.AddRow ar(i) active.Add ar(i).productIdentifier end if next i next identifier Return active() End Function
Protected Sub GetAllKnownProducts() Dim productIDs() As String //Add all identifiers for your subscriptions and one-time purchases #if not DebugBuild #Pragma error "Change your productIDs here" #endif productIDs.Add "<<app.premium.month.3" productIDs.Add "<<app.premium.year.10" GetProductInfoWithCallback(nil, productIDs) End Sub
Protected Function GetPrice(productID As String, divide12 As Boolean = False) As String For Each p As SKProductMBS In ProductRequest.validProducts If p.productIdentifier = productID Then Dim loc As new Locale( p.priceLocale.localeIdentifier ) Dim c As Currency = p.price if divide12 then c = Round(c/12*100)/100 End If Dim price As String = c.ToString(loc) Return price End If Next End Function
Protected Function GetProduct(productID As String) As SKProductMBS For Each p As SKProductMBS In ProductRequest.validProducts If p.productIdentifier = productID Then Return p End If Next End Function
Protected Sub GetProductInfo(list As iOSMobileTable, Identifiers() As String) // Your application creates an SKProductsRequest object and initializes it with a set // of product identifiers for the items you wish to sell, attaches a delegate to the // request, and then starts it. The response holds the localized product information // for all valid product identifiers. Your application cannot create a payment request // unless you have first retrieved the product information for that product. Dim ids() as String for each id as String in Identifiers if kIAPPrefix.IsEmpty = False and id.BeginsWith(kIAPPrefix) = False then ids.Add kIAPPrefix + id else ids.Add id end if next ProductRequest = New myProductsRequest(ids) ProductRequest.list = list ProductRequest.Start End Sub
Protected Sub GetProductInfo(list As iOSMobileTable, paramarray Identifier As String) // Your application creates an SKProductsRequest object and initializes it with a set // of product identifiers for the items you wish to sell, attaches a delegate to the // request, and then starts it. The response holds the localized product information // for all valid product identifiers. Your application cannot create a payment request // unless you have first retrieved the product information for that product. GetProductInfo(list, Identifier) End Sub
Protected Sub GetProductInfoWithCallback(callback As myProductsRequest.ReceivedResponseDelegate, Identifiers() As String) // Your application creates an SKProductsRequest object and initializes it with a set // of product identifiers for the items you wish to sell, attaches a delegate to the // request, and then starts it. The response holds the localized product information // for all valid product identifiers. Your application cannot create a payment request // unless you have first retrieved the product information for that product. For i as Integer = 0 to Identifiers.lastindex Dim id As String = Identifiers(i) if kIAPPrefix.IsEmpty = False and id.BeginsWith(kIAPPrefix) = False then id = kIAPPrefix + "." + id Identifiers(i) = id end if Next ProductRequest = New myProductsRequest(Identifiers) ProductRequest.callback = callback ProductRequest.Start End Sub
Protected Sub GetProductInfoWithCallback(callback As myProductsRequest.ReceivedResponseDelegate, paramarray Identifier As String) // Your application creates an SKProductsRequest object and initializes it with a set // of product identifiers for the items you wish to sell, attaches a delegate to the // request, and then starts it. The response holds the localized product information // for all valid product identifiers. Your application cannot create a payment request // unless you have first retrieved the product information for that product. GetProductInfoWithCallback(callback, Identifier) End Sub
Protected Function GetSavingsPercent(prodYear As SKProductMBS, prodMonth As SKProductMBS) As String Dim percent As Double = ((prodYear.price - prodMonth.price * 12)/(prodMonth.price * 12)) Dim savings As String = localSavePercent if savings <> "%1" then percent = percent * -1 end if savings = savings.Replace("%1", percent.ToString(locale.Current, "0%")) Return savings End Function
Protected Sub Init() // Register a transaction observer with the payment queue. // Your application should instantiate a transaction observer and add it as an observer of the payment queue. // Your application should add the observer when your application launches. // The App Store remembers queued transactions even if your application exited before completing // all transactions. Adding an observer during initialization ensures that all previously // queued transactions are seen by your application. PaymentQueue = new myPaymentQueue End Sub
Protected Sub PurchaseProduct(p as SKProductMBS, callback as myPaymentQueue.UpdatedTransactionsDelegate) Dim t As New SKPaymentMBS(p) PaymentQueue.UpdatedTransactionsCallback = callback PaymentQueue.addPayment t End Sub
Protected Sub PurchaseProduct(productID as String, callback as myPaymentQueue.UpdatedTransactionsDelegate) dim found As Boolean For Each p As SKProductMBS In ProductRequest.validProducts If p.productIdentifier = productID Then PurchaseProduct(p, callback) found = true exit End If Next #if app.useSentry if not found then break try Dim err As new RuntimeException err.Message = productID + " not found" raise err Catch err2 app.sentry.SubmitException(err2, CurrentMethodName + " not found") end try end if #endif End Sub
Protected Sub RestoreTransactions(updateCallback as myPaymentQueue.updatedTransactionsDelegate, failedCallback as myPaymentQueue.RestoreFailedDelegate) if PaymentQueue is nil then init() end if PaymentQueue.UpdatedTransactionsCallback = updateCallback PaymentQueue.RestoreFailedCallback = failedCallback PaymentQueue.restoreCompletedTransactions End Sub
Protected Function getSubscriptionInfo(forID as String) As AppReceiptIAPMBS var a() as AppReceiptIAPMBS for i as integer = 0 to subscriptions.LastIndex if subscriptions(i).productIdentifier.trim.Lowercase=forID.trim.Lowercase then a.add subscriptions(i) end if next i if a.Count=0 then return nil if a.Count=1 then return a(0) var newest as AppReceiptIAPMBS for i as integer = 0 to a.LastIndex if newest = nil then newest = a(i) continue end if if a(i).subscriptionExpirationDateTime > newest.subscriptionExpirationDateTime then newest=a(i) continue end if next i if newest<>nil then var dt as DateTime = newest.cancellationDateTime break end if return newest Exception return nil End Function
Protected Function isSubscriptionValid(id as String) As boolean var a as AppReceiptIAPMBS = getSubscriptionInfo(id) if a = nil then return false if a.cancellationDateTime<>nil then var d as datetime = datetime.now return a.subscriptionExpirationDateTime > d and a.cancellationDateTime > d else return a.subscriptionExpirationDateTime >= datetime.now end if Exception return false End Function
Property Protected PaymentQueue As myPaymentQueue
Property Protected ProductRequest As myProductsRequest
Property Protected highlight As cIAPController.Highlights
Property Private mfirstPurchase As DateTime
Property Protected subscriptionIDs() As String
Property Protected subscriptions() As AppReceiptIAPMBS
End Module
Class cIAPController
Const localBuyNow = Buy Now %1
Const localErrorAppStoreConnection = Cannot connect to the iTunes/App Store. Please try again.
Const localIAPAlreadyPurchased = Already purchased?
Const localIAPBlockedPayments = In-App payments seem to be restricted
Const localIAPNotFound = In-App product not found
Const localIAPNotPurchased = You haven’t purchased "%t" yet
Const localIAPRestoredPurchase = Your previous purchase has been restored
Const localIAPSpecialOffer = Special offer ends in %T
Const localIAPSpecialOfferSimple = 🎁 Special offer 🎁
Const localNotAvailable = Not available
Const localOneTimePurchase = One time purchase %1
Const localPurchaseFailed = Purchase Failed
Const localRecentReviews = Recent Reviews
Const localRestore = Already purchased? Restore
Const localXPriceInsteadOfY = instead of %Y
Enum Highlights None quotes categories reminders themes ads welcome End Enum
Protected Sub Destructor() End Sub
Sub LogPurchase(productID As String) //This method is used to log a purchase in your global database if necessary End Sub
Sub LogPurchaseView(products() As String, variation As String, highlight As cIAPController.Highlights, promo As Boolean, subscription As Boolean, offering As String = "") //This method is used to log a purchase page view in your global database if necessary self.displaydate = DateTime.Now self.variation = variation //Do something End Sub
Protected Sub RestoreTransactions() PaymentQueue.restoreCompletedTransactions End Sub
Property IAPMode As String = "B"
Property Protected displaydate As DateTime
Property Private purchase_viewsID As String
Property variation As String
End Class
Class myProductsRequest Inherits SKProductsRequestMBS
Delegate Sub ReceivedResponseDelegate(Success As Boolean)
EventHandler Sub didFailWithError(error as NSErrorMBS) #if DebugBuild System.DebugLog CurrentMethodName MessageBox AppStoreModule.cIAPController.localErrorAppStoreConnection + &u0A + error.localizedDescription #endif 'MessageBox "Failed with error: "+error.localizedDescription if callback <> nil then callback.Invoke(False) end if End EventHandler
EventHandler Sub didFinish() self.completed = True #if DebugBuild System.DebugLog CurrentMethodName #endif End EventHandler
EventHandler Sub didReceiveResponse(products() as SKProductMBS, invalidProductIdentifiers() as string) #if DebugBuild System.DebugLog CurrentMethodName #endif For Each p As SKProductMBS In products #if DebugBuild System.DebugLog CurrentMethodName + " product: "+p.localizedTitle #endif validProducts.Add p if list <> nil then Dim cd As MobileTableCellData = list.CreateCell(p.localizedTitle, p.localizedDescription+" "+p.priceString) cd.Tag = p list.AddRow(0, cd) end if next If ExtensionsXC.IsTestflightXC then if invalidProductIdentifiers.Count > 0 then MessageBox "Invalid: " + EndOfLine + string.FromArray(invalidProductIdentifiers) End If End If for each i as string in invalidProductIdentifiers #if DebugBuild 'Break System.DebugLog CurrentMethodName + "invalid: "+i #endif if list <> nil then Dim cd As MobileTableCellData = list.CreateCell(i, "Invalid product identifier") list.AddRow(0, cd) end if next if callback <> nil then callback.Invoke(true) end if list = nil callback = nil End EventHandler
Property callback As ReceivedResponseDelegate
Property completed As Boolean
Property list As iOSMobileTable
Property validProducts() As SKProductMBS
End Class
Class vIAPVertical Inherits MobileScreen
Control Table Inherits iOSMobileTable
ControlInstance Table Inherits iOSMobileTable
Constraint Constraint 1
Constraint Constraint 2
Constraint Constraint 3
Constraint Constraint 4
Constraint Constraint 5
Constraint Constraint 6
EventHandler Sub SelectionChanged(section As Integer, row As Integer) Dim sectionTag As Variant = datasource.sections(section).tag if sectionTag.StringValue = "purchaseoptions" then Dim clickedOption as dPurchaseOption = datasource.RowDicData(section, row).Value("tag") if clickedOption is nil then Return if clickedOption.selected then //Nothing Else clickedOption.selected = True self.selectedPurchaseOption = clickedOption for i as Integer = 0 to datasource.RowCount(Table, section)-1 Dim opt as dPurchaseOption = datasource.RowDicData(section, i).Value("tag") if opt <> nil and opt <> clickedOption then opt.selected = False end if next lblCancel.Visible = clickedOption.subscription end if me.ReloadDataInSection(section) Return end if if section = me.SectionCount-2 then If me.RowCellData(section, row).tag = "restore" then Restore() Return End If elseif section = me.SectionCount-1 then Dim tag As String = me.RowCellData(section, row).Tag.StringValue select case tag Case "top" me.ScrollToRow(0, 0, true, iOSMobileTable.ScrollPositions.Middle) Case "restore" Restore() case "privacy" #if not DebugBuild #Pragma error "Change your privacy url" #endif System.GotoURL("<<your privacy url>>") Case "terms" #if not DebugBuild #Pragma error "Change your terms url" #endif System.GotoURL("<<your terms url>>") end select end if End EventHandler
End Control
Control Separator1 Inherits MobileSeparator
ControlInstance Separator1 Inherits MobileSeparator
Constraint Constraint 1
Constraint Constraint 2
Constraint Constraint 3
Constraint Constraint 4
End Control
Control Label1 Inherits Mobilebutton
ControlInstance Label1 Inherits Mobilebutton
Constraint Constraint 1
Constraint Constraint 2
Constraint Constraint 3
Constraint Constraint 4
EventHandler Sub Opening() Dim strDiamond As String = "💎" //Diamond me.Caption = "Get Premium" + " " + strDiamond me.SetBackgroundColorXC(cgTint) me.SetCornerRadiusXC(8) me.CaptionColor = &cFFFFFF End EventHandler
End Control
Control Rectangle1 Inherits MobileRectangle
ControlInstance Rectangle1 Inherits MobileRectangle
Constraint Constraint 1
Constraint Constraint 2
Constraint Constraint 3
End Control
Control btBuy Inherits MobileButton
ControlInstance btBuy Inherits MobileButton
Constraint Constraint 1
Constraint Constraint 2
Constraint Constraint 3
Constraint Constraint 4
Constraint Constraint 5
EventHandler Sub Pressed() Purchase(selectedPurchaseOption.productID) End EventHandler
End Control
Control lblCancel Inherits MobileLabel
ControlInstance lblCancel Inherits MobileLabel
Constraint Constraint 1
Constraint Constraint 2
Constraint Constraint 3
Constraint Constraint 4
EventHandler Sub Opening() 'me.TextColor = AppTheme. me.Text = localCancelAnytime me.AdjustsFontSizeToFitWidthXC End EventHandler
End Control
EventHandler Sub Activated() self.SetNavBarTransparentXC() End EventHandler
EventHandler Sub AppearanceChanged(dark As Boolean) self.SetNavBarTransparentXC() Rectangle1.FillColor = cgSystemBackground btBuy.SetCornerRadiusXC(50/2) if self.RightNavigationToolbar.Count > 0 then SetCloseButton end if End EventHandler
EventHandler Sub Closing() self.controller = nil if AppStoreModule.PaymentQueue <> nil then AppStoreModule.PaymentQueue.RestoreFailedCallback = nil AppStoreModule.PaymentQueue.UpdatedTransactionsCallback = nil end if JK_NotificationCenter.MainCenter.PostNotification("paywall_close", self) End EventHandler
EventHandler Sub Opening() me.Title = "" btBuy.Caption = localContinue btBuy.SetBackgroundColorXC(cgTint) btBuy.SetCornerRadiusXC(15) btBuy.CaptionColor = color.White Dim annualy, monthly, perYear, perMonth As String annualy = localAnnualy monthly = localMonthly perYear = localPerYear perMonth = localPerMonth timer.CallLater(2000, AddressOf SetCloseButton) //Cancelled ok Self.AddProgressXC(Progress) if controller is nil then controller = new cIAPController end if //Set the defaults: #if not DebugBuild #Pragma error "Need to change the purchase IDs" #endif self.monthlyID = "<<app.premium.month.3" self.annualID = "<<app.premium.year.10" LoadOffering() #if DebugBuild 'self.lifetimeID = "" #endif LoadProducts() LoadTable End EventHandler
EventHandler Sub ToolbarButtonPressed(button As MobileToolbarButton) // Part of the iScrollViewCC interface. Dim buttonTag As String = button.Tag select case buttonTag Case "debug" 'StoreKit.InAppPurchaseHelper.SKProvideContentForProductNotification Case "restore" AppStoreModule.RestoreTransactions(WeakAddressOf RestoreCompleted, WeakAddressOf RestoreFailed) Case "close" self.Close Else Break //Unknown button end select End EventHandler
Sub Constructor(highlight As cIAPController.Highlights) // Calling the overridden superclass constructor. // Note that this may need modifications if there are multiple constructor choices. // Possible constructor calls: // Constructor() -- From iOSContainerControl // Constructor() -- From iOSControl // Constructor(deserializer As xojo.Core._Deserializer) -- From iOSControl 'self.BigpromoID = Foundation.NSUserDefaults.StandardUserDefaults.TextForKey("bigpromo") Self.highlight = highlight 'self.LoadSchemeAndProducts(iapID) Super.Constructor End Sub
Protected Sub Dismiss() self.Close 'self.DismissViewControllerXC End Sub
Private Function GetPurchaseOptions() As dPurchaseOption() Dim options() as dPurchaseOption Dim prodYear As SKProductMBS = AppStoreModule.GetProduct(annualID) Dim prodMonth As SKProductMBS = AppStoreModule.GetProduct(monthlyID) Dim po As dPurchaseOption if prodYear is nil then Return options() end if Dim price As String Dim pricePerYear As String = localPricePerYear Dim pricePerMonth As String = localPricePerMonth price = pricePerYear.Replace("2.99", AppStoreModule.GetPrice(annualID)) Dim cancelCaption As String = localCancelAnytime lblCancel.Text = cancelCaption //Monthly po = new dPurchaseOption options.Add po po.productID = monthlyID po.callback = WeakAddressOf Purchase po.subscription = True po.title = localMonthly po.price = pricePerMonth.Replace("2.99", AppStoreModule.GetPrice(monthlyID, False)) po.save = "" po.img1 = nil po.caption1 = "" //////////////////// //Annualy po = new dPurchaseOption po.selected = true self.selectedPurchaseOption = po options.Add po po.subscription = True po.productID = annualID po.callback = WeakAddressOf Purchase po.title = localAnnualy po.price = price po.priceTotal = "(" + pricePerMonth.Replace("2.99", AppStoreModule.GetPrice(annualID, true)) + ")" '+ " (" + price + ")" po.cancel = cancelCaption if prodYear <> nil and prodMonth <> nil then Dim savings As String = AppStoreModule.GetSavingsPercent(prodYear, prodMonth) po.save = savings po.save = po.save.Uppercase end if if isFree then po.productID = productID po.price = AppStoreModule.GetPrice(productID) po.priceTotal = "" po.save = "Free" po.cancel = "" end if //Lifetime if lifetimeID.IsEmpty = False then Dim prodLifetime As SKProductMBS = AppStoreModule.GetProduct(lifetimeID) if prodLifetime <> nil then po = new dPurchaseOption options.Add po po.subscription = False po.productID = lifetimeID po.callback = WeakAddressOf Purchase po.title = localLifetime po.price = AppStoreModule.GetPrice(lifetimeID, False) po.save = "" end if end if Return options End Function
Protected Sub LoadOffering() //This method is optional. //If your app has different offerings setup on RevenueCat, use this method to select the correct one Dim offeringIdentifier As String = "3_10" //This is the RevenueCat offering identifier //New v2.4.4 //Load the offerings if not loaded yet if RevenueCat.HasOfferings = False then Dim rvc As new RevenueCat rvc.Init end if Dim offering As RevenueCatOffering = RevenueCat.GetOffering(offeringIdentifier) if offering is nil and offeringIdentifier.BeginsWith("Subscription_") = False then offeringIdentifier = "Subscription_" + offeringIdentifier offering = RevenueCat.GetOffering(offeringIdentifier) end if if offering <> nil then For each package as RevenueCatOfferingPackage in offering.packages if package.identifier = "$rc_annual" then self.annualID = package.platform_product_identifier Elseif package.identifier = "$rc_monthly" then self.monthlyID = package.platform_product_identifier elseif package.identifier = "$rc_lifetime" then self.lifetimeID = package.platform_product_identifier elseif package.identifier = "$rc_weekly" then self.weeklyID = package.platform_product_identifier end if Next Else offeringIdentifier = "" end if Globals.presented_offering_identifier = offeringIdentifier End Sub
Private Sub LoadProducts() Dim productIDs() As String productIDs.Add self.annualID productIDs.Add self.monthlyID #if not DebugBuild #Pragma error "Add more product identifiers if necessary #endif 'productIDs.Add "" //Reorder the product IDs Dim idx As Integer idx = productIDs.IndexOf(self.monthlyID) if idx > -1 then productIDs.RemoveAt(idx) end if idx = productIDs.IndexOf(self.annualID) if idx > -1 then productIDs.RemoveAt(idx) end if productIDs.AddAt(0, self.monthlyID) productIDs.AddAt(1, self.annualID) if self.lifetimeID.IsEmpty = False then idx = productIDs.IndexOf(self.lifetimeID) if idx > -1 then productIDs.RemoveAt(idx) end if productIDs.AddAt(2, self.lifetimeID) end if AppStoreModule.Init AppStoreModule.GetProductInfoWithCallback(AddressOf LoadProductsCompleted, productIDs) dim isPromo as boolean = (dateSpecialOfferEnd <> nil) Dim variation As String variation = "Vertical_v1" controller.LogPurchaseView(productIDs, variation, self.highlight, isPromo, True, globals.presented_offering_identifier) End Sub
Protected Sub LoadProductsCompleted(Success As Boolean) self.Progress.Visible = False If Not Success Then MessageBox(controller.localErrorAppStoreConnection) btBuy.Enabled = False 'btBuy.SetBackgroundColorXC(AppTheme.SkeletonColorDark) btBuy.AnimateAlphaXC(0.5) Return End If btBuy.Enabled = True if datasource <> nil then Dim section as Integer = 0 Dim options() as dPurchaseOption = GetPurchaseOptions datasource.Sections(section).rows.RemoveAll for each opt as dPurchaseOption in options datasource.AddRow(section, "") datasource.LastRowDicData(section).Value("tag") = opt datasource.LastRowDicData(section).Value("type") = "cellPurchaseFullWidth" next table.ReloadDataInSection(0) end if End Sub
Protected Sub LoadTable() table.TintColor = cgTint self.datasource = new dsPurchase Dim section As Integer Dim caption, detail As String Dim icon As Picture Dim accessory As MobileTableCellData.AccessoryTypes = MobileTableCellData.AccessoryTypes.None Dim iconSize As Integer = 20 Dim iconWeight As Picture.SystemImageWeights = Picture.SystemImageWeights.Medium dim firstSectionTitle As String = "" if table.Format = iOSMobileTable.Formats.InsetGrouped then firstSectionTitle = " " end if section = datasource.AddSection(firstSectionTitle) datasource.Sections(section).tag = "purchaseoptions" #if False caption = OnlineLoc("localPremiumAnnualDescription",localPremiumAnnualDescription, localPremiumAnnualDescription("en"), False) if caption.isTranslated then datasource.Sections(section).title = "" datasource.AddRow(section, localPremiumAnnualDescription) if isIPad or isiPhoneX then datasource.LastRowDicData(section).Value("Roundedfont30") = true datasource.LastRowDicData(section).Value("alignment") = ControlExtensionsXC.NSTextAlignment.center else datasource.LastRowDicData(section).Value("Roundedfont22") = true datasource.LastRowDicData(section).Value("alignment") = ControlExtensionsXC.NSTextAlignment.natural end if datasource.LastRowDicData(section).Value("lines") = 3 datasource.LastRowDicData(section).Value("type") = "cellTitle" end if #endif //Purchase options Dim options() as dPurchaseOption = GetPurchaseOptions() for each opt as dPurchaseOption in options datasource.AddRow(section, "", "", MobileTableCellData.AccessoryTypes.None, opt) datasource.LastRowDicData(section).Value("type") = "cellPurchaseFullWidth" next /////////////// //Features /////////////// caption = " " section = datasource.AddSection(caption) Dim imgCheck As Picture = Picture.SystemImage("checkmark.circle.fill", iconSize, iconWeight, nil) //Categories caption = "Unlock this special feature 🚀" detail = "" datasource.AddRow(section, caption, detail, accessory, nil, imgCheck) //No Ads caption = "No ads ❌" detail = "" icon = Picture.SystemImage("nosign", iconSize, iconWeight) datasource.AddRow(section, caption, detail, accessory, nil, icon) //Family Sharing caption = localFamilySharing if caption.Contains(" ") = False then section = datasource.AddSection("") icon = Picture.SystemImage("figure.2.and.child.holdinghands", iconSize, iconWeight) if icon <> nil then datasource.AddRow(section, caption, "", accessory, nil, icon) end if end if ////////////////// // Restore ////////////////// section = datasource.AddSection("") datasource.AddRow(section, "", localRestore, MobileTableCellData.AccessoryTypes.None, "restore", Picture.SystemImage("arrow.clockwise", 14)) ////////////////// // Terms of Use / Privacy ////////////////// section = datasource.AddSection("") caption = localTermsOfUse datasource.AddRow(section, "", caption, MobileTableCellData.AccessoryTypes.None, "terms", Picture.SystemImage("doc.text", 14)) caption = localPrivacyPolicy datasource.AddRow(section, "", caption, MobileTableCellData.AccessoryTypes.None, "privacy", Picture.SystemImage("shield.lefthalf.filled", 14)) 'datasource.LastRowDicData(section).Value("textColor") = cgTint table.DataSource = datasource End Sub
Protected Sub Purchase(productID As String) If SKPaymentQueueMBS.canMakePayments Then ShowProgressHUD() self.productID = productID 'if isFree then '//Nothing 'elseif ccPurchaseYear.Selected then 'self.productID = productID 'Elseif true then 'if ccPurchaseMonth.Selected then 'self.productID = productID 'Else 'Break 'end if AppStoreModule.PurchaseProduct(self.productID, WeakAddressOf updatedTransactions) Else 'MessageBox "Can't make payments with this computer. App Store not setup?" MessageBox cIAPController.localIAPBlockedPayments End If End Sub
Protected Sub Restore() ShowProgressHUD() AppStoreModule.RestoreTransactions(WeakAddressOf RestoreCompleted, WeakAddressOf RestoreFailed) Return End Sub
Private Sub RestoreCompleted(transactions() as SKPaymentTransactionMBS) self.progress.Visible = False if self.progressHUD <> nil then self.progressHUD.hide(true) end if Dim success As Boolean for each transaction as SKPaymentTransactionMBS in transactions Select case transaction.transactionState case SKPaymentTransactionMBS.StatePurchased success = True case SKPaymentTransactionMBS.StateFailed case SKPaymentTransactionMBS.StateRestored success = True end Select next if success then MessageBox(cIAPController.localIAPRestoredPurchase) end if End Sub
Private Sub RestoreFailed(Error as NSErrorMBS) self.progress.Visible = False if self.progressHUD <> nil then self.progressHUD.hide(true) end if MessageBox( "Error" + &u0A + Error.LocalizedDescription ) End Sub
Protected Sub SetCloseButton() self.RightNavigationToolbar.RemoveAllButtons Dim tbClose As MobileToolbarButton ' = AppTheme.GetCloseButton Dim pic As Picture = Picture.SystemImage("xmark", 0, Picture.SystemImageWeights.Regular) tbClose = new MobileToolbarButton(MobileToolbarButton.Types.Done, if(pic=nil, "Close", ""), pic) tbClose.Tag = "close" If self.RightNavigationToolbar.Count = 0 Then self.RightNavigationToolbar.AddButton tbClose Else self.LeftNavigationToolbar.AddButton tbClose End If End Sub
Protected Sub ShowProgressHUD() progressHUD = new MyProgressHUD(self) progressHUD.Mode = MyProgressHUD.ModeIndeterminate progressHUD.RemoveFromSuperViewOnHide = True progressHUD.backgroundView.ColorValue = &c000000A0 progressHUD.backgroundView.Style = progressHUD.backgroundView.BackgroundStyleSolidColor progressHUD.show() End Sub
Private Sub updatedTransactions(transactions() as SKPaymentTransactionMBS) for each transaction as SKPaymentTransactionMBS in transactions Select case transaction.transactionState case SKPaymentTransactionMBS.StatePurchased Dim identifier As String = transaction.payment.productIdentifier if identifier.Contains("yearly") or identifier.Contains("monthly") then NSUserDefaults.SetBoolForKey(True, "subscription") end if //Ok to close self.Close Return case SKPaymentTransactionMBS.StatePurchasing case SKPaymentTransactionMBS.StateFailed if Progress <> nil then Progress.Visible = False end if if progressHUD <> nil then progressHUD.hide(true) end if // Finish the transaction for a failed purchase. if transaction.error.code <> StoreKitMBS.SKErrorPaymentCancelled then // Optionally, display an error here. MessageBox "Error" + EndOfLine + EndOfLine + _ Transaction.error.localizedDescription + EndOfLine + EndOfLine + _ transaction.Error.Code.ToString end if case SKPaymentTransactionMBS.StateRestored if AppStoreModule.isSubscriptionValid(transaction.payment.productIdentifier) then MessageBox(cIAPController.localIAPRestoredPurchase) Return end if end Select next End Sub
Property Private Progress As MobileProgressWheel
Property Protected RatingsLoaded As Boolean
Property Protected annualID As String
Property Private caption2 As Text
Property controller As cIAPController
Property Private datasource As dsPurchase
Property Private Shared dateSpecialOfferEnd As DateTime
Property Private headerImageView As MobileImageViewer
Property highlight As cIAPController.Highlights
Property isFree As Boolean
Property Protected jsRatings As Text
Property lifetimeID As String
Property loadFail As Integer
Property Protected monthlyID As String
Property productID As String
Property productIDRich As Text
Property progressHUD As MyProgressHUD
Property selectedPurchaseOption As dPurchaseOption
Property Protected weeklyID As String
End Class
Class dsPurchase Inherits myDatasource
Protected Function RowData(table As iOSMobileTable, section As Integer, row As Integer) As MobileTableCellData // Part of the iOSMobileTableDataSource interface. #if DebugBuild Dim sectionName As String sectionName = GetSectionTitle(section) #endif Dim cell As MobileTableCellData Dim rows() As Dictionary rows = sections(section).rows Dim nd As Dictionary = rows(row) if nd.HasKey("type") then Dim type As String = nd.Value("type") Select case type Case "cellPurchaseOptions" Break 'cell = table.CreateCustomCell(GetTypeInfo(cellPurchaseOptions)) ' 'cellPurchaseOptions(cell.Control).Setup(nd.Value("tag")) Case "cellPurchaseFullWidth" cell = table.CreateCustomCell(GetTypeInfo(cellPurchaseFullWidth)) cellPurchaseFullWidth(cell.Control).option = (nd.Value("tag")) cell.SetSelectionStyleXC(TableExtensionsXC.selectionStyle.none) Return cell Case "cellPurchaseRatings" Break Case "cellTitle" cell = table.CreateCell Dim value As String = nd.Value("Text") Dim detail As String = nd.Value("detail") cell.Text = value cell.DetailText = detail cell.Image = nd.Lookup("image", Nil) cell.AccessoryType = nd.Value("accessory") cell.Tag = nd.Value("tag") if nd.HasKey("lines") then cell.AdjustsFontSizeToFitWidthXC(nd.Value("lines")) else cell.AdjustsFontSizeToFitWidthXC(2) end if cell.SetTableCellDetailBreakXC(ControlExtensionsXC.NSLineBreakMode.WordWrap, 3) cell.SetSelectionStyleXC(TableExtensionsXC.selectionStyle.none) if nd.HasKey("textColor") then cell.SetTextColorXC(nd.Value("textColor")) end if End Select cell.SetSelectionStyleXC(TableExtensionsXC.selectionStyle.none) else cell = table.CreateCell("") Dim value As String = nd.Value("Text") Dim detail As String = nd.Value("detail") cell.Text = value cell.DetailText = detail cell.Image = nd.Lookup("image", Nil) cell.AccessoryType = nd.Value("accessory") 'cell.TextColorXC = AppTheme.TableTextColor cell.Tag = nd.Value("tag") 'cell.AccessoryType = nd.Value( if nd.HasKey("lines") then cell.AdjustsFontSizeToFitWidthXC(nd.Value("lines")) else cell.AdjustsFontSizeToFitWidthXC(2) end if cell.SetTableCellDetailBreakXC(ControlExtensionsXC.NSLineBreakMode.WordWrap, 3) cell.SetSelectionStyleXC(TableExtensionsXC.selectionStyle.none) if nd.HasKey("textColor") then cell.SetTextColorXC(nd.Value("textColor")) end if end if Return cell End Function
Property variation As String
End Class
Class dPurchaseOption
Delegate Sub PurchaseDelegate(productID As String)
Property callback As PurchaseDelegate
Property cancel As String
Property caption1 As String
Property caption2 As String
Property description As String
Property img1 As Picture
Property img2 As Picture
Property price As String
Property priceTotal As String
Property productID As String
Property save As String
Property selected As Boolean
Property subscription As Boolean
Property tag As String
Property title As String
End Class
Class cellPurchaseFullWidth Inherits MobileTableCustomCell
ComputedProperty option As dPurchaseOption
Sub Set() moption = value if value.selected then ImageViewer1.Image = Picture.SystemImage("checkmark.circle.fill", 0) ImageViewer1.TintColor = cgTint Rectangle1.BorderColor = cgTint else ImageViewer1.Image = Picture.SystemImage("circle.fill", 0) ImageViewer1.TintColor = cgSecondarySystemFill Rectangle1.BorderColor = cgSecondarySystemFill end if lblTitle.Text = value.title lblTitle.TextColor = cgTextColor Dim ft As Font = font.BoldSystemFont(20) lblTitle.TextFont = ft 'lblTitle.AdjustsFontForContentSizeCategoryXC(UIFontTextStyle.body, ft, 30) lblTitle.AdjustsFontSizeToFitWidthXC(1) if value.subscription = False then lblPrice.Text = value.priceTotal + " " + value.price else lblPrice.Text = value.price end if lblPrice.TextColor = cgTextColor lblPrice.AdjustsFontForContentSizeCategoryXC(UIFontTextStyle.body) lblPrice.AdjustsFontSizeToFitWidthXC(1) if value.priceTotal.IsEmpty = False then lblPriceTotal.Visible = True lblPriceTotal.Text = value.priceTotal lblPriceTotal.TextColor = cgSecondaryLabel lblPriceTotal.AdjustsFontForContentSizeCategoryXC(UIFontTextStyle.subHeadline) lblPriceTotal.AdjustsFontSizeToFitWidthXC(1) Else lblPriceTotal.Visible = False end if if not value.save.IsEmpty then lblSave.AdjustsFontSizeToFitWidthXC Declare Sub userInteractionEnabled Lib UIKitLib Selector "setUserInteractionEnabled:" _ (obj As ptr, value As Boolean) userInteractionEnabled(lblSave.handle, False) lblSave.SetBackgroundColorXC(cgRed) lblSave.SetCornerRadiusXC(26/2) lblSave.CaptionColor = &cFFFFFF 'if lblSave.Caption <> value.save then lblSave.Caption = value.save 'lblSave.SetAlphaValueXC(0.0) 'lblSave.Visible = true 'lblSave.AnimateAlphaXC(1.0) 'Else lblSave.Visible = True 'end if 'lblSave.Caption = OnlineLoc("localBestDeal", localBestDeal, localBestDeal("en"), False).Uppercase 'me.SetButtonInsetsXC(ExtensionsXC.UIEdgeInsetMake(0, 4, 0, 4)) Else lblSave.Caption = "" lblSave.Visible = False end if End Set
Sub Get() Return moption End Get
End ComputedProperty
Control Rectangle1 Inherits MobileRectangle
ControlInstance Rectangle1 Inherits MobileRectangle
Constraint Constraint 1
Constraint Constraint 2
Constraint Constraint 3
Constraint Constraint 4
End Control
Control lblTitle Inherits MobileLabel
ControlInstance lblTitle Inherits MobileLabel
Constraint Constraint 1
Constraint Constraint 2
Constraint Constraint 3
Constraint Constraint 4
End Control
Control lblPrice Inherits MobileLabel
ControlInstance lblPrice Inherits MobileLabel
Constraint Constraint 1
Constraint Constraint 2
Constraint Constraint 3
Constraint Constraint 4
Constraint Constraint 5
End Control
Control ImageViewer1 Inherits MobileImageViewer
ControlInstance ImageViewer1 Inherits MobileImageViewer
Constraint Constraint 1
Constraint Constraint 2
Constraint Constraint 3
Constraint Constraint 4
End Control
Control lblSave Inherits MobileButton
ControlInstance lblSave Inherits MobileButton
Constraint Constraint 1
Constraint Constraint 2
Constraint Constraint 3
Constraint Constraint 4
Constraint Constraint 5
EventHandler Sub Opening() me.SetBackgroundColorXC(color.Red) me.SetCornerRadiusXC(8) me.CaptionColor = &cFFFFFF me.Caption = localBestDeal 'me.SetButtonInsetsXC(ExtensionsXC.UIEdgeInsetMake(0, 4, 0, 4)) me.AdjustsFontSizeToFitWidthXC Declare Sub userInteractionEnabled Lib UIKitLib Selector "setUserInteractionEnabled:" _ (obj As ptr, value As Boolean) userInteractionEnabled(me.handle, False) End EventHandler
End Control
Control lblPriceTotal Inherits MobileLabel
ControlInstance lblPriceTotal Inherits MobileLabel
Constraint Constraint 1
Constraint Constraint 2
Constraint Constraint 3
Constraint Constraint 4
End Control
Property Private moption As dPurchaseOption
End Class
Class datasourceSection
Property allrows() As Dictionary
Property collapsed As Boolean
Property rows() As Dictionary
//Was xojo.core.dictionary
Property tag As Variant
Property title As String
End Class
Class myDatasource
ComputedProperty myTable As iOSMobileTable
Sub Set() mmyTableRef = xojo.Core.WeakRef.Create(value) End Set
Sub Get() if mmyTableRef <> nil then return iOSMobileTable(mmyTableRef.Value) End If End Get
End ComputedProperty
Const kLastupdate = 20181220
Delegate Sub MobileRowEditingDelegate(tag As Auto, action As iOSMobileTable . RowEditingStyles)
Delegate Sub RowEditingDelegate(tag As Auto, action As iOSMobileTable . RowEditingStyles)
Sub AddRow(section As Integer, title As String, detail As String = "", Accessory As MobileTableCellData.AccessoryTypes = MobileTableCellData.AccessoryTypes.None, tag As Auto = nil, image As Picture = nil) 'section As Integer, Text As Text, detail As Text, Accessory As MobileTableCellData.AccessoryTypes = MobileTableCellData.AccessoryTypes.Disclosure, tag As Auto, image As iOSImage = Nil dim nd As new Dictionary nd.Value("text") = Title nd.Value("detail") = detail nd.Value("accessory") = Accessory nd.Value("image") = image nd.Value("tag") = tag sections(section).rows.Add nd End Sub
Sub AddSection(title As String, tag As Auto = nil) Dim s As new datasourceSection s.title = title s.tag = tag s.collapsed = False Sections.Add s End Sub
Function AddSection(title As String, tag As Auto = nil) As Integer AddSection(title, tag) Return Sections.LastIndex End Function
Sub Constructor() End Sub
Protected Function GetSectionTitle(section As Integer) As String Return sections(section).title End Function
Sub InsertRow(index As Integer, section As Integer, title As String, detail As String, Accessory As MobileTableCellData.AccessoryTypes = MobileTableCellData.AccessoryTypes.Disclosure, tag As Auto) dim nd As new Dictionary nd.Value("text") = title nd.Value("detail") = detail nd.Value("accessory") = Accessory nd.Value("tag") = tag Dim rows() As Dictionary try sections(section).rows.Insert(index, nd) Catch err Try If section > sections.LastIndex Then err.Message = err.Message + &u0A + "Section greater than section count" Elseif index > rows.LastIndex+1 Then err.Message = err.Message + &u0A + "Index greater than row count" End If Catch End Try End Try End Sub
Sub InsertSection(index As Integer, title As String = "", tag As Auto = nil) Dim s As new datasourceSection s.title = title s.tag = tag s.collapsed = False Sections.Insert(index, s) End Sub
Function LastRowDicData(section As Integer) As Dictionary Dim rows() As Dictionary rows = sections(section).rows Return RowDicData(section, rows.LastIndex) End Function
Sub RemoveAllSections() Sections.ResizeTo(-1) End Sub
Sub RemoveRow(section As Integer, row As Integer) Dim rows() As Dictionary rows = sections(section).rows if row > -1 and row <= rows.LastIndex then //error #1370 rows.Remove row Else Break //Should never happen End If End Sub
Sub RemoveSection(index as Integer) sections.Remove(index) End Sub
Function RowCount(table As iOSMobileTable, section As Integer) As Integer // Part of the iOSMobileTableDataSource interface. If myTable = Nil Then myTable = table End If If section = -1 Or section > sections.LastIndex Then Return 0 End If Dim sectionData As datasourceSection = sections(section) Return sectionData.rows.Count End Function
Protected Function RowData(table As iOSMobileTable, section As Integer, row As Integer) As MobileTableCellData // Part of the iOSMobileTableDataSource interface. #if DebugBuild Dim sectionName As String sectionName = GetSectionTitle(section) #endif Dim cell As MobileTableCellData Dim rows() As Dictionary rows = sections(section).rows Dim nd as Dictionary = rows(row) cell = table.CreateCell() cell.Text = nd.Value("text") cell.DetailText = nd.Value("detail") cell.Image = nd.Lookup("image", Nil) cell.AccessoryType = nd.Value("accessory") cell.Tag = nd.Value("tag") Return cell End Function
Function RowDicData(section As Integer, row As Integer) As Dictionary #if DebugBuild Dim sectionName As String sectionName = GetSectionTitle(section) #endif Dim rows() As Dictionary rows = sections(section).rows If row <= rows.LastIndex Then Return rows(row) End If End Function
Function SectionCount(table as iOSMobileTable) As Integer // Part of the iOSMobileTableDataSource interface. #Pragma Unused table Return sections.Count End Function
Function SectionData(section as Integer) As datasourceSection If section = -1 Then Return nil End If Return sections(section) End Function
Private Function SectionTitle(table As iOSMobileTable, section As Integer) As String // Part of the iOSMobileTableDataSource interface. #pragma Unused table Return GetSectionTitle(section) End Function
Property Private mmyTableRef As Xojo.Core.WeakRef
Property sections() As datasourceSection
End Class
Module Notification_Center
End Module
Class NotificationRelation
ComputedProperty Observer As Object
Sub Set() 'mObserver = value mObserver = xojo.Core.WeakRef.Create(value) End Set
Sub Get() 'Return mObserver if mObserver <> nil then Return mObserver.Value end if End Get
End ComputedProperty
Sub Constructor(observer as object, callback as JK_NotificationCenter.NotificationCallBack, notificationName as text, sender as object) self.Observer = observer self.CallBack = callback self.NotificationName = notificationName self.Sender = sender End Sub
Sub SendNotification(anotification As JK_Notification) CallBack.Invoke(aNotification) End Sub
Function WantsNotification(aNotification As JK_Notification) As Boolean dim wants as Boolean = False if NotificationName = "" and sender = nil then //accepts all notifications from all sources wants = True end if if NotificationName = aNotification.Name and (sender = aNotification.Sender or Sender = nil) then //accepts notifications with this name from all senders or the sender is the accepted sender wants = True end if if Sender = aNotification.Sender and NotificationName = "" then //accepts all notifications from this sender wants = true end if Return wants End Function
Property CallBack As JK_NotificationCenter.NotificationCallBack
Property NotificationName As text
Property Sender As Object
Property Private mObserver As xojo.Core.WeakRef
End Class
Class JK_Notification
ComputedProperty Sender As Object
Sub Set() mSender = xojo.Core.WeakRef.Create(value) End Set
Sub Get() return mSender.Value End Get
End ComputedProperty
Sub Constructor(notificationName as Text, sender as Object) self.Constructor(notificationName,sender,nil) End Sub
Sub Constructor(notificationName as Text, sender as object, userInfoDict as Dictionary) self.Name = notificationName self.Sender = sender self.UserInfo = userInfoDict End Sub
Private Sub Destructor() mSender = nil End Sub
Property Name As Text
Property UserInfo As Dictionary
Property Private mSender As xojo.Core.WeakRef
End Class
Class JK_NotificationCenter
Delegate Sub NotificationCallBack(aNotification As JK_Notification)
Private Sub Cleanup() Dim u as Integer = relations.LastIndex for i as integer = u DownTo 0 if relations(i).observer is nil then relations.Remove(i) end if next End Sub
Private Sub Constructor() End Sub
Function HasObserverForNotification(aNotification As JK_Notification) As Boolean //jly Cleanup for i as Integer = 0 to relations.LastIndex If relations(i).WantsNotification(aNotification) then Return True end if next End Function
Shared Function MainCenter() As JK_NotificationCenter static mcenter as JK_NotificationCenter if mcenter = nil then mcenter = new JK_NotificationCenter end if Return mcenter End Function
Sub PostNotification(aNotification As JK_Notification) if aNotification = nil then Break 'A posted notification cannot be nil. Return end if //Do some cleanup if necessary Cleanup Dim found As Boolean for i as Integer = 0 to relations.LastIndex If relations(i).WantsNotification(aNotification) then relations(i).SendNotification(aNotification) found = true end if next #if DebugBuild if not found then System.DebugLog CurrentMethodName + ": couldn't find a receiver for " + aNotification.Name found = found end if #endif End Sub
Sub PostNotification(name as text, sender as object) PostNotification(name,sender,nil) End Sub
Sub PostNotification(name as text, sender as object, userInfo as Dictionary) PostNotification(new JK_Notification(name, sender, userInfo)) End Sub
Sub PostNotificationDelayed(afterMsec As Integer, aNotification As JK_Notification) if aNotification = nil then Break 'A posted notification cannot be nil. Return end if timer.CallLater(afterMsec, AddressOf PostNotificationDelayed_internal, aNotification) End Sub
Protected Sub PostNotificationDelayed_internal(value as Variant) Dim aNotification as JK_Notification = value self.PostNotification(aNotification) End Sub
Sub addObserver(observer as object, callback as NotificationCallBack, notificationName as text, sender as object) if callback = nil then break ' The callback for a notification must not be nil Return end if dim nr as new NotificationRelation(observer, callback,notificationName,sender) relations.Add nr End Sub
Sub addObservers(observer as object, callback as NotificationCallBack, notificationNames() as text, sender as object) if callback = nil then break ' The callback for a notification must not be nil Return end if For each notificationName as text in notificationNames dim nr as new NotificationRelation(observer, callback,notificationName,sender) relations.Add nr Next End Sub
Sub removeObserver(observer as Object) removeObserver(observer,"",nil) End Sub
Sub removeObserver(observer as object, notificationName as text, sender as object) dim tmpRelation as NotificationRelation for i as Integer = relations.LastIndex DownTo 0 tmpRelation = relations(i) if tmpRelation.Observer = observer then //observer is correct if notificationName = "" then //all notifications if tmpRelation.sender = sender or sender = nil then //sender matches relations.Remove i end if ElseIf tmpRelation.NotificationName = notificationName then //notificationName matches if tmpRelation.sender = sender or sender = nil then //sender matches relations.Remove i end if end if end if next End Sub
Property Private relations() As NotificationRelation
End Class
Class RevenueCat Inherits URLConnection
Const kDefaultOfferings = "{}"
EventHandler Sub ContentReceived(URL As String, HTTPStatus As Integer, content As String) self.requestInProgress = False if content.Encoding is nil then content = content.DefineEncoding(Encodings.UTF8) end if if HTTPStatus > 201 then if DebugBuild or ExtensionsXC.IsTestflightXC then MessageBox(url + EndOfLine + EndOfLine + content) end if if HTTPStatus <> 429 and url.Contains("attributes") = False then Dim err As new RuntimeException Break end if Return end if If HTTPStatus = 200 then if self.parseEntitlements then self.parseEntitlements = False try Dim dic As Dictionary = ParseJSON(content) if dic.HasKey("subscriber") then dim dicSubscriber As Dictionary = dic.Value("subscriber") if dicSubscriber.HasKey("entitlements") then Dim dicEntitlements As Dictionary = dicSubscriber.Value("entitlements") self.entitlements = dicEntitlements NSUserDefaults.SetTextForKey(GenerateJSON(dicEntitlements), "RevenueCatEntitlements_" + Globals.userID) end if end if Catch err #if app.useSentry app.sentry.AddExtraKeyValue("content", content) app.sentry.AddExtraKeyValue("URL", url) app.sentry.SubmitException(err, CurrentMethodName + "_entitlements") #endif end try Elseif self.parseOfferings then self.parseOfferings = False try Dim dic As Dictionary = ParseJSON(content) if dic.HasKey("offerings") then Dim vOfferings() as Variant = dic.Value("offerings") For each o as Dictionary in vOfferings self.offerings.Add new RevenueCatOffering(o) Next Dim value As String = GenerateJSON(dic.Value("offerings")) NSUserDefaults.SetTextForKey(value, "RevenueCatOfferings_" + Globals.userID) end if Catch err #if app.useSentry app.sentry.AddExtraKeyValue("content", content) app.sentry.AddExtraKeyValue("URL", url) app.sentry.SubmitException(err, CurrentMethodName + "_offerings") #endif end try End If else self.parseOfferings = False self.parseEntitlements = False End If End EventHandler
EventHandler Sub Error(e As RuntimeException) Static fails As Integer fails = fails + 1 if self.lastURL.Contains("offerings") then Timer.CallLater(min(30000, fails*1000), AddressOf GetOfferingsDefaultUserID) end if self.parseOfferings = False self.parseEntitlements = False self.requestInProgress = False End EventHandler
Private Sub Authorization() self.ClearRequestHeaders #if not DebugBuild #Pragma error "Change your RevenueCat API token here" #endif dim decodedString as String = "<<YOUR REVENUECAT API>>" if decodedString.BeginsWith("<<") then Break Return end if self.RequestHeader("Authorization") = "Bearer " + decodedString self.RequestHeader("accept") = "application/json" self.RequestHeader("X-Platform") = "iOS" Dim userID As String if Globals.userID.IsEmpty then userID = "0" else userID = Globals.userID end if self.RequestHeader("X-Version") = "4.23.0" self.RequestHeader("X-Platform-Version") = System.Version.ToString self.RequestHeader("X-Platform-Flavor") = "native" self.RequestHeader("X-Client-Version") = app.Version self.RequestHeader("X-Client-Build-Version") = app.NonReleaseVersion.ToString End Sub
Sub CreateSubscriber(userID As String) self.Authorization() 'self.RequestHeader("X-Platform-Version") = "1.0" 'self.RequestHeader("X-Observer-Mode-Enabled") = "false" 'self.RequestHeader("X-Is-Sandbox") = "false" self.parseEntitlements = True Dim url As String = "https://api.revenuecat.com/v1/subscribers/" + userID self.debug_postData = "" self.requestInProgress = True self.Send("GET", url) self.last_send_method = "GET" self.lastURL = url End Sub
Shared Function GetOffering(identifier As String) As RevenueCatOffering if offerings.Count = 0 then Return nil for each off as RevenueCatOffering in offerings if off.identifier = identifier then Return off end if next End Function
Sub GetOfferings(userID As String) if userID.IsEmpty or userID = "0" then Return end if self.Authorization self.RequestHeader("X-Platform") = "ios" self.parseOfferings = True Dim url As String = "https://api.revenuecat.com/v1/subscribers/" + userID + "/offerings" self.debug_postData = "" self.requestInProgress = True self.Send("GET", url) self.last_send_method = "GET" self.lastURL = url End Sub
Sub GetOfferingsDefaultUserID() Dim userID As String = Globals.userID if userID.isEmpty = False and userID <> "0" then GetOfferings(userID) end if End Sub
Shared Function HasEntitlement(name As String) As Boolean if entitlements is nil then Return False if not entitlements.HasKey(name) then Return False try Dim entitlement As Dictionary = entitlements.Value(name) Dim expires_date As String = entitlement.value("expires_date").stringvalue.Replace("T", " ").Replace("Z", "") if expires_date.IsEmpty then Return True //No expiration Dim tz As new TimeZone(0) Dim expires_datetime As DateTime = datetime.FromString(expires_date, nil, tz) if expires_datetime.SecondsFrom1970 > DateTime.Now.SecondsFrom1970 then Return True Catch err #if app.useSentry app.sentry.SubmitException(err, CurrentMethodName) #endif end try Return False End Function
Shared Function HasOfferings() As Boolean Return offerings.Count > 0 End Function
Sub Init() Dim userID As String = globals.userID if self.entitlements is nil then Dim entitlements As String = NSUserDefaults.TextForKey("RevenueCatEntitlements_" + userID) if entitlements.IsEmpty or entitlements = "{}" then //Don't parse Else try Dim dicEntitlements As Dictionary = ParseJSON(entitlements) self.entitlements = dicEntitlements Catch err end try end if end if if self.offerings.Count = 0 then //Loading offerings from NSUSerDefaults Dim offerings as String = NSUserDefaults.TextForKey("RevenueCatOfferings_" + userID) if offerings.IsEmpty = False and offerings.Length > 10 then Dim vOfferings() as Variant = ParseJSON(offerings) For each o as Dictionary in vOfferings self.offerings.Add new RevenueCatOffering(o) Next Else //Loading offerings from the default value Dim dic As Dictionary = ParseJSON(kDefaultOfferings) if dic.HasKey("offerings") then Dim vOfferings() as Variant = dic.Value("offerings") For each o as Dictionary in vOfferings self.offerings.Add new RevenueCatOffering(o) Next end if end if end if End Sub
Sub RecordPreviousPurchase() if NSUserDefaults.BoolForKey("SentOldReceiptToRevenueCat") then Return Static doneOnce as Boolean if doneOnce then Return doneOnce = True self.RecordPurchase("", False, 0.0, "") NSUserDefaults.SetBoolForKey(True, "SentOldReceiptToRevenueCat") End Sub
Sub RecordPurchase(product_id As String, is_restore As Boolean, price As Double, currencyValue As String) self.Authorization self.parseEntitlements = true self.RequestHeader("X-Platform") = "ios" Dim url As String = "https://api.revenuecat.com/v1/receipts" dim data As new Dictionary data.Value("app_user_id") = Globals.userID Declare Function mainBundle Lib "Foundation" selector "mainBundle" (clsRef As ptr) As ptr Declare Function NSClassFromString Lib "Foundation" (name As CFStringRef) As Ptr Declare Function appStoreReceiptURL lib "Foundation" selector "appStoreReceiptURL" (obj as ptr) as ptr Declare function path lib "Foundation" selector "path" (obj as ptr) as CFStringRef Declare Function base64EncodedStringWithOptions Lib "UIKit" Selector "base64EncodedStringWithOptions:" (data As Ptr, options As UInt32) As CFStringRef declare function dataWithContentsOfURL_ lib "Foundation" selector "dataWithContentsOfURL:" (clsRef as ptr, aURL as ptr) as ptr Dim theURL As Ptr = appStoreReceiptURL(mainBundle(NSClassFromString("NSBundle"))) if theURL <> nil then Dim receiptURLString as Text = path(theURL) Dim receiptData as ptr = dataWithContentsOfURL_(NSClassFromString("NSData"), theURL) Dim t as string = base64EncodedStringWithOptions(receiptData, 0) data.Value("fetch_token") = t Else Break Return end if if not product_id.IsEmpty then data.Value("product_id") = product_id end if data.Value("is_restore") = is_restore if price > 0.0 then data.Value("price") = price data.Value("currency") = currencyValue end if //The offering identifier if Globals.presented_offering_identifier.IsEmpty = False then data.Value("presented_offering_identifier") = Globals.presented_offering_identifier end if data.Value("store_country") = locale.Current.Identifier.Right(2) //Attributes Dim dicAttributes As new Dictionary 'dicAttributes.Value("$idfv") = new Dictionary("value": Session.user_uuid) if Globals.user_email.isEmpty = False then dicAttributes.Value("$email") = new Dictionary("value": Globals.user_email) end if data.Value("attributes") = dicAttributes dim postData as String = GenerateJSON(data) self.debug_postData = postData Me.SetRequestContent(postData, "application/json") self.requestInProgress = True self.Send("POST", url) self.last_send_method = "GET" self.lastURL = url NSUserDefaults.SetBoolForKey(True, "SentOldReceiptToRevenueCat") End Sub
Protected Sub SendAttributes() if self.requestInProgress then timer.CancelCallLater(AddressOf SendAttributes) timer.CallLater(10000, AddressOf SendAttributes) Return end if Dim userID As String = Globals.userID if userID.isEmpty or userID = "0" then timer.CancelCallLater(AddressOf SendAttributes) timer.CallLater(10000, AddressOf SendAttributes) Return end if if dicAttributes is nil or dicAttributes.KeyCount = 0 then Return self.Authorization Dim url as string = "https://api.revenuecat.com/v1/subscribers/" + userID + "/attributes" dim data As new Dictionary Dim now As Double = DateTime.Now.SecondsFrom1970 * 1000 Dim epoch As String = now.ToString(locale.Raw, "#") data.Value("attributes") = dicAttributes dim postData as String = GenerateJSON(data) self.debug_postData = postData Me.SetRequestContent(postData, "application/json") self.requestInProgress = True self.send("POST", url) self.last_send_method = "GET" self.lastURL = url End Sub
Sub UpdateAttribute(key As String, value As Variant, delayed As Boolean = True) Dim p As new pair(key, value) self.UpdateAttributes(Array(p), delayed) End Sub
Sub UpdateAttributes(entries() As Pair, delayed As Boolean = true) #if DebugBuild if Globals.userID.isEmpty then Return end if #endif //Attributes if dicAttributes is nil then dicAttributes = new Dictionary end if for each p as pair in entries dicAttributes.Value(p.Left) = new Dictionary("value": p.Right.StringValue) ', "updated_at_ms": epoch) next if delayed then timer.CancelCallLater(AddressOf SendAttributes) timer.CallLater(10000, AddressOf SendAttributes) Return end if SendAttributes End Sub
Property Private ChineseNetwork As Boolean
Property debug_postData As String
Property Protected dicAttributes As Dictionary
Property Private Shared entitlements As Dictionary
Property Private lastURL As String
Property Private last_send_method As String
Property Private Shared offerings() As RevenueCatOffering
Property Private parseEntitlements As Boolean
Property Private parseOfferings As Boolean
Property Private requestInProgress As Boolean
End Class
Class RevenueCatOffering
Sub Constructor(dic As Dictionary) self.identifier = dic.Value("identifier") self.description = dic.Lookup("description", "") if dic.HasKey("packages") then Dim vPackages() As Variant = dic.Value("packages") for each pack as Dictionary in vPackages self.packages.Add new RevenueCatOfferingPackage(pack) next end if End Sub
Property description As String
Property identifier As String
Property packages() As RevenueCatOfferingPackage
End Class
Class RevenueCatOfferingPackage
Sub Constructor(dic As Dictionary) self.identifier = dic.Value("identifier") self.platform_product_identifier = dic.Value("platform_product_identifier") End Sub
Property identifier As String
Property platform_product_identifier As String
End Class
Module NSUserDefaults
Protected Function BoolForKey(defaultName as CFStringRef) As Boolean Dim defaults As ptr = StandardUserDefaults() declare function boolForKey_ lib "Foundation" selector "boolForKey:" (obj_id as ptr, defaultName as CFStringRef) as Boolean Return boolForKey_(defaults, defaultName) End Function
Protected Function IntegerForKey(defaultName As String) As Integer Dim defaults As ptr = StandardUserDefaults() declare function integerForKey_ lib "Foundation.framework" selector "integerForKey:" (obj_id as ptr, defaultName as CFStringRef) as Integer Return integerForKey_(defaults, defaultName) End Function
Protected Sub RemoveObjectForKey(defaultName As String) Dim defaults As ptr = StandardUserDefaults() declare sub removeObjectForKey_ lib "Foundation.framework" selector "removeObjectForKey:" (obj_id as ptr, defaultName as CFStringRef) removeObjectForKey_(defaults, defaultName) End Sub
Protected Sub SetBoolForKey(value As boolean, defaultName As String) Dim defaults As ptr = StandardUserDefaults() declare sub setBool_ lib "Foundation.framework" selector "setBool:forKey:" (obj_id as ptr, value as Boolean, defaultName as CFStringRef) setBool_(defaults, value, defaultName) End Sub
Protected Sub SetIntegerForKey(value As Integer, defaultName As String) Dim defaults As ptr = StandardUserDefaults() declare sub setInteger_ lib "Foundation.framework" selector "setInteger:forKey:" (obj_id as ptr, value as Integer, defaultName as CFStringRef) setInteger_(defaults, value, defaultName) End Sub
Protected Sub SetTextForKey(value As String, defaultName As CFStringRef) Dim defaults As ptr = StandardUserDefaults() Declare Function NSClassFromString Lib "Foundation.framework" (clsName As CFStringRef) As Ptr Declare Function stringWithString Lib "Foundation.framework" Selector "stringWithString:" (cls As Ptr, value As CFStringRef) As Ptr Dim s As ptr = stringWithString( NSClassFromString("NSString"), value) declare sub setObject_ lib "Foundation.framework" selector "setObject:forKey:" (obj_id as ptr, value as ptr, defaultName as CFStringRef) setObject_(defaults, s, defaultName) End Sub
Private Function StandardUserDefaults() As ptr Declare Function NSClassFromString Lib "Foundation.framework" (clsName As CFStringRef) As Ptr Declare Function standardUserDefaults_ Lib "Foundation.framework" Selector "standardUserDefaults" (clsRef As Ptr) As Ptr static ClassRef as ptr = NSClassFromString("NSUserDefaults") 'declare function alloc lib "Foundation.framework" selector "alloc" (clsRef as ptr) as ptr declare function initWithSuiteName_ lib "Foundation.framework" selector "initWithSuiteName:" (obj_id as ptr, suitename as CFStringRef) as ptr 'Dim defaults as ptr = initWithSuiteName_(alloc(ClassRef), standardUserDefaults_(ClassRef)) ) Static defaults As ptr = standardUserDefaults_(ClassRef) Return defaults End Function
Private Sub StandardUserDefaultsSynchronize() declare function synchronize_ lib "Foundation.framework" selector "synchronize" (obj_id as ptr) as Boolean call synchronize_(StandardUserDefaults) End Sub
Protected Function TextForKey(defaultName As String) As CFStringRef Dim defaults As ptr = StandardUserDefaults() declare function stringForKey_ lib "Foundation.framework" selector "stringForKey:" (obj_id as ptr, defaultName as CFStringRef) as CFStringRef Return stringForKey_(defaults, defaultName) End Function
End Module
Module Globals
Property Protected presented_offering_identifier As String
Property Protected userID As String
Property Protected user_email As String
End Module
Class MyProgressHUD Inherits ProgressHUDMBS
EventHandler Sub buttonAction() me.cancel = True End EventHandler
EventHandler Sub hudWasHidden() End EventHandler
Property cancel As Boolean
End Class
Module ButtonExtensionsXC
Enum UIButtonRole normal = 0 primary cancel destructive End Enum
Sub AdjustsFontForContentSizeCategoryXC(extends button As MobileButton, textStyle As ControlExtensionsXC.UIFontTextStyle, customFont As Font = nil, maxPointSize As Double = 0.0) Dim label As ptr Declare Function getTextLabel Lib "UIKit.framework" selector "titleLabel" (obj_ref As ptr) As ptr label = getTextLabel(button.Handle) ControlExtensionsXC.AdjustsFontForContentSizeCategoryXC_internal(label, textStyle, customFont, maxPointSize) End Sub
Sub AdjustsFontSizeToFitWidthXC(extends bt As MobileButton, lines As Integer = -1) Dim label As ptr Declare Function getTextLabel Lib "UIKit.framework" selector "titleLabel" (obj_ref As ptr) As ptr label = getTextLabel(bt.Handle) If lines > 0 Then Declare Sub setNumberOfLines Lib "UIKit.framework" selector "setNumberOfLines:" (id As ptr, value As Integer) setNumberOfLines label, lines End If Declare Sub setAdjustsFontSizeToFitWidth Lib "UIKit.framework" selector "setAdjustsFontSizeToFitWidth:" (id As ptr, value As Boolean) setAdjustsFontSizeToFitWidth label, True End Sub
Sub SetBackdropXC(extends bt as MobileButton, backdrop as Picture) 'This method was posted by Jim McKay in the https://forum.xojo.com/18184-button-and-view-colours-ios/last thread 'on 12/12/2014 Declare Sub setBackgroundImage Lib "UIKit" selector "setBackgroundImage:forState:" (obj As ptr, value As ptr, state As Integer) if backdrop is nil then setBackgroundImage(bt.Handle, nil, 0) else Dim bestImage As Picture = ImageExtensionsXC.BestRepresentationXC(backdrop) setBackgroundImage(bt.Handle, bestImage.CopyOSHandle(Picture.HandleType.iOSUIImage), 0) end if End Sub
Sub SetBorderWidthXC(extends bt As MobileButton, value As Double) Declare Function layer_ Lib "UIKit.framework" selector "layer" (id As ptr) As Ptr Dim layer As ptr = layer_(bt.Handle) Declare Sub setBorderWidth Lib "UIKit.framework" selector "setBorderWidth:" (obj_id As ptr, st As CGFloat) setBorderWidth(layer, value) End Sub
Sub SetButtonInsetsXC(extends bt As MobileButton, value As ExtensionsXC.xcUIEdgeInsets) Declare Sub setContentEdgeInsets Lib "UIKit.framework" selector "setContentEdgeInsets:" (id As ptr, value As ExtensionsXC.xcUIEdgeInsets) setContentEdgeInsets (bt.handle, value) End Sub
Sub SetButtonTiledBackgroundXC(extends bt As MobileButton, img As Picture) Dim insets As ExtensionsXC.xcUIEdgeInsets insets.Left = 12 insets.Top = 12 insets.Bottom = 12 insets.Right = 12 Dim resizedImg as Picture resizedImg = ImageExtensionsXC.ResizableTiledImageXC(insets, img) bt.SetBackdropXC(resizedImg) bt.SetButtonInsetsXC(insets) End Sub
Sub SetContentHorizontalAlignmentXC(extends bt As MobileButton, alignment As ControlExtensionsXC.UIControlContentHorizontalAlignment) declare sub setContentHorizontalAlignment lib "UIKit" Selector "setContentHorizontalAlignment:" (obj as ptr, value as ControlExtensionsXC.UIControlContentHorizontalAlignment) setContentHorizontalAlignment(bt.Handle, alignment) End Sub
Sub SetImageInsetsXC(extends bt As MobileButton, value As ExtensionsXC.xcUIEdgeInsets) Declare Sub setImageEdgeInsets Lib "UIKit.framework" selector "setImageEdgeInsets:" (id As ptr, value As ExtensionsXC.xcUIEdgeInsets) setImageEdgeInsets (bt.handle, value) End Sub
Sub SetImageXC(extends bt As MobileButton, image As Picture, state As ControlExtensionsXC.UIControlState = ControlExtensionsXC.UIControlState.normal) 'This method was posted by Jim McKay in the https://forum.xojo.com/18184-button-and-view-colours-ios/last thread 'on 12/12/2014 Declare Sub setImage Lib "UIKit.framework" selector "setImage:forState:" (obj As ptr, value As ptr, state As ControlExtensionsXC.UIControlState) If image Is Nil Then setImage(bt.Handle, Nil, state) Else Dim bestImg As Picture = ImageExtensionsXC.BestRepresentationXC(image) setImage(bt.Handle, bestImg.Handle, state) End If End Sub
Sub SetLineBreakModeXC(extends bt As MobileButton, mode As ControlExtensionsXC.NSLineBreakMode) Dim label As ptr Declare Function getTextLabel Lib "UIKit.framework" selector "titleLabel" (obj_ref As ptr) As ptr label = getTextLabel(bt.Handle) Declare Sub setLineBreakMode Lib "UIKit.framework" selector "setLineBreakMode:" (id As ptr, value As ControlExtensionsXC.NSLineBreakMode) setLineBreakMode label, mode End Sub
Sub SetNumberOfLinesXC(extends bt As MobileButton, lines As Integer) Dim label As ptr Declare Function getTextLabel Lib "UIKit.framework" selector "titleLabel" (obj_ref As ptr) As ptr label = getTextLabel(bt.Handle) Declare Sub setTextAlignment Lib "UIKit.framework" selector "setTextAlignment:" (id As ptr, value As ControlExtensionsXC.NSTextAlignment) 'setTextAlignment(label, NSTextAlignment.center) Declare Sub setNumberOfLines Lib "UIKit.framework" selector "setNumberOfLines:" (id As ptr, value As Integer) setNumberOfLines label, lines End Sub
Sub SetRoleXC(extends bt As MobileButton, value As ButtonExtensionsXC.UIButtonRole) //New in version 2.0 if ExtensionsXC.GetiOSVersionXC >= 14.0 then Declare Sub setRole Lib "UIKit.framework" selector "setRole:" (obj_id As ptr, aRole As UIButtonRole) setRole(bt.handle, value) end if End Sub
Sub SetTextAlignmentXC(extends bt As MobileButton, alignment As ControlExtensionsXC.NSTextAlignment) Dim label As ptr Declare Function getTextLabel Lib "UIKit.framework" selector "titleLabel" (obj_ref As ptr) As ptr label = getTextLabel(bt.Handle) Declare Sub setTextAlignment Lib "UIKit.framework" selector "setTextAlignment:" (id As ptr, value As ControlExtensionsXC.NSTextAlignment) setTextAlignment(label, alignment) End Sub
Sub SetTitleEdgeInsetsXC(extends bt As MobileButton, value As ExtensionsXC.xcUIEdgeInsets) Declare Sub setTitleEdgeInsets_ Lib "UIKit.framework" selector "setTitleEdgeInsets:" (id As ptr, value As ExtensionsXC.xcUIEdgeInsets) setTitleEdgeInsets_ (bt.handle, value) End Sub
Sub x_SetBackgroundColorXC(Extends bt As MobileButton, value As color) Declare Function NSClassFromString Lib "Foundation" (className As CFStringRef) As Ptr Declare Function colorWithRGBA Lib "UIKit.framework" Selector "colorWithRed:green:blue:alpha:" ( UIColorClassRef As Ptr, red As CGFloat, green As CGFloat, blue As CGFloat, alpha As CGFloat) As Ptr Declare Function view Lib "UIKit.framework" Selector "view" (UIViewController As Ptr) As Ptr Declare Sub setBackgroundColor Lib "UIKit.framework" Selector "setBackgroundColor:" (UIView As Ptr, UIColor As Ptr) Dim UIColorClassPtr As Ptr = NSClassFromString("UIColor") Dim colorPtr As ptr = colorWithRGBA(UIColorClassPtr, (value.red / 255.0), (value.Green / 255.0), (value.Blue / 255.0), (1.0-value.Alpha/255.0)) Dim viewPtr As Ptr = bt.Handle SetBackgroundColor(viewPtr, colorPtr) End Sub
Sub x_SetBorderColorXC(extends bt As MobileButton, value As Color) Declare Function layer_ Lib "UIKit.framework" selector "layer" (id As ptr) As Ptr Dim layer As ptr = layer_(bt.Handle) Dim uic As UIKit.UIColor If value.Alpha = 255 Then uic = UIKit.UIColor.ClearColor Else uic = New UIColor(value) End If declare sub setBorderColor lib "UIKit.framework" selector "setBorderColor:" (obj_id as ptr, col as ptr) setBorderColor(layer, uic.CGColor) End Sub
End Module
Module ControlExtensionsXC
Enum NSLineBreakMode WordWrap = 0 CharacterWrap Clip TruncateHead TruncateTail TruncateMiddle End Enum
Enum NSTextAlignment left = 0 center right justified natural End Enum
Enum UIActivityIndicatorViewStyle whiteLarge white gray End Enum
Enum UIControlContentHorizontalAlignment Center = 0 Left Right Fill Leading Trailing End Enum
Enum UIControlState normal highlighted disabled selected focused End Enum
Enum UIDatePickerStyle automatic = 0 wheels compact inline End Enum
Enum UIFontTextStyle body callout caption1 caption2 footnote headline subHeadline largeTitle title1 title2 title3 End Enum
Enum UIUserInterfaceStyle Unspecified Light Dark End Enum
Enum UIUserInterfaceStyle1 unspecified = 0 light = 1 dark = 2 End Enum
Enum UIVIewAnimationCurve EaseInEaseOut EaseIn EaseOut Linear Keyboard = 7 End Enum
Enum UIVIewAnimationTransition None FlipFromLeft FlipFromRight CurlUp CurlDown CrossDissolve FlipFromTop FlipFromBottom End Enum
Sub AdjustsFontForContentSizeCategoryXC(extends ctrl As MobileTextControl, textStyle As ControlExtensionsXC.UIFontTextStyle, customFont As Font = nil, maxPointSize As Double = 0.0) ControlExtensionsXC.AdjustsFontForContentSizeCategoryXC_internal(ctrl.Handle, textStyle, customFont, maxPointSize) End Sub
Protected Sub AdjustsFontForContentSizeCategoryXC_internal(label As Ptr, textStyle As ControlExtensionsXC.UIFontTextStyle, customFont As Font = nil, maxPointSize As Double = 0.0) Declare Function NSClassFromString Lib "Foundation" (className As CFStringRef) As Ptr Declare Function alloc Lib "Foundation.framework" selector "alloc" (clsRef As ptr) As ptr Declare Function initFont Lib "UIKit.framework" selector "fontWithName:size:" (obj_id As ptr, name As CFStringRef, size As CGFloat) As ptr Declare Function preferredFontForTextStyle Lib "UIKit.framework" selector "preferredFontForTextStyle:" (obj_id As ptr, mode As CFStringRef) As ptr Declare function metricsForTextStyle lib "UIKit.framework" selector "metricsForTextStyle:" (clsRef as ptr, mode As CFStringRef) as ptr Declare function scaledFontForFontmaximumPointSize lib "UIKit.framework" selector "scaledFontForFont:maximumPointSize:" (obj as ptr, font as ptr, pointSize As CGFloat) as ptr Declare function scaledFontForFont lib "UIKit.framework" selector "scaledFontForFont:" (obj as ptr, font as ptr) as ptr Dim constName As String Select case textStyle Case UIFontTextStyle.body constName = "UIFontTextStyleBody" Case UIFontTextStyle.callout constName = "UIFontTextStyleCallout" Case UIFontTextStyle.caption1 constName = "UIFontTextStyleCaption1" Case UIFontTextStyle.caption2 constName = "UIFontTextStyleCaption2" Case UIFontTextStyle.footnote constName = "UIFontTextStyleFootnote" Case UIFontTextStyle.headline constName = "UIFontTextStyleHeadline" Case UIFontTextStyle.subHeadline constName = "UIFontTextStyleSubheadline" Case UIFontTextStyle.largeTitle constName = "UIFontTextStyleLargeTitle" Case UIFontTextStyle.title1 constName = "UIFontTextStyleTitle1" Case UIFontTextStyle.title2 constName = "UIFontTextStyleTitle2" case UIFontTextStyle.title3 constName = "UIFontTextStyleTitle3" End Select Dim textStylePtr As Ptr = ExtensionsXC.LoadConstantXC("UIKit", constName) Dim fontPtr As ptr if customFont <> nil then 'Declare Function initFont Lib "UIKit.framework" selector "fontWithName:size:" (obj_id As ptr, name As CFStringRef, size As CGFloat) As ptr Dim fontMetricsPtr As Ptr = metricsForTextStyle((NSClassFromString("UIFontMetrics")), textStylePtr.CFStringRef(0)) Dim customFontPtr As Ptr customFontPtr = initFont(NSClassFromString("UIFont"), customFont.Name, customFont.Size) if maxPointSize > 0.0 then //Returns a version of the specified font that adopts the current font metrics and is constrained to the specified maximum size. fontPtr = scaledFontForFontmaximumPointSize(fontMetricsPtr, customFontPtr, maxPointSize) Else //Returns a version of the specified font that adopts the current font metrics. fontPtr = scaledFontForFont(fontMetricsPtr, customFontPtr) end if Else fontPtr = preferredFontForTextStyle((NSClassFromString("UIFont")), textStylePtr.CFStringRef(0)) if maxPointSize > 0.0 then Dim fontMetricsPtr As Ptr = metricsForTextStyle((NSClassFromString("UIFontMetrics")), textStylePtr.CFStringRef(0)) fontPtr = scaledFontForFontmaximumPointSize(fontMetricsPtr, fontPtr, maxPointSize) end if end if Declare sub setFont lib "UIKit.framework" selector "setFont:" (obj_ref as ptr, fontRef as ptr) Declare Sub setAdjustsFontForContentSizeCategory Lib "UIKit.framework" Selector "setAdjustsFontForContentSizeCategory:" (obj_ref as ptr, value as Boolean) setFont(label, fontPtr) setAdjustsFontForContentSizeCategory label, True End Sub
Sub AdjustsFontSizeToFitWidthXC(extends label As MobileLabel, lines As Integer = -1) label.LineBreakMode = MobileLabel.LineBreakModes.TruncateEnd If lines > 0 Then Declare Sub setNumberOfLines Lib "UIKit.framework" selector "setNumberOfLines:" (id As ptr, value As Integer) setNumberOfLines label.handle, lines End If Declare sub setAdjustsFontSizeToFitWidth lib "UIKit.framework" selector "setAdjustsFontSizeToFitWidth:" (id as ptr, value as Boolean) setAdjustsFontSizeToFitWidth label.handle, True End Sub
Sub AnimateAlphaXC(extends ctrl as MobileUIControl, newAlpha as double, duration as double = 0.2, completion as iOSBlock = nil) #If ExtensionsXC.kUseUIKit Dim v As New UIView(ctrl.Handle) v.AnimateAlpha newalpha, duration, completion #else #Pragma Unused ctrl #Pragma Unused newalpha #Pragma Unused duration #Pragma Unused completion #EndIf End Sub
Sub FlipHorizontalForRTLXC(extends c As MobileUIControl) //Flips an MobileUIControl on the horizontal axis for RTL Declare sub transform lib "UIKit.framework" selector "setTransform:" (obj_id as ptr, matrix as ExtensionsXC.xcCGAffineTransform) Declare function CGAffineTransformMakeScale lib "CoreGraphics.framework" (sx as CGFloat, sy as CGFloat) as ExtensionsXC.xcCGAffineTransform Dim scale As ExtensionsXC.xcCGAffineTransform scale = CGAffineTransformMakeScale(-1, 1) transform(c.Handle, scale) End Sub
Function GetBoundsXC(extends c as MobileUIControl) As Rect 'Declare Function view_ Lib "UIKit.framework" selector "view" (controlHandle As ptr) As Ptr Declare Function bounds Lib "UIKit.framework" selector "bounds" (obj_id As Ptr) As ExtensionsXC.xcCGRect 'Dim view As Ptr = view_(c.handle) Dim re As ExtensionsXC.xcCGRect = bounds(c.handle) Return New Rect(re.origin.x, re.origin.y, re.rsize.width, re.rsize.height) End Function
Function GetFrameXC(extends c as MobileUIControl) As Rect Dim viewRef As ptr = c.Handle Declare Function frame Lib "UIKit.framework" selector "frame" (obj_id As Ptr) As ExtensionsXC.xcCGRect Dim re As ExtensionsXC.xcCGRect = frame(viewRef) Return New Rect(re.origin.x, re.origin.y, re.rsize.width, re.rsize.height) End Function
Sub PopToRootViewControllerXC(extends v As MobileScreen, animated As Boolean = true) //Reference to Navigation Controller declare function navigationController lib "UIKit.framework" selector "navigationController" (viewController as ptr) as ptr dim navigationControllerRef as ptr = navigationController(v.ViewControllerHandle) declare function popToRootViewController_ lib "UIKit.framework" selector "popToRootViewControllerAnimated:" (obj_ref as ptr, aniamted As Boolean) as ptr call popToRootViewController_(navigationControllerRef, animated) End Sub
Sub RemoveConstraintsXC(extends screen As MobileScreen) // http://stackoverflow.com/questions/13388104/remove-auto-layout-constraints-for-specific-object '[detailsPhotoView removeConstraints:detailsPhotoView.constraints]; Declare sub removeConstraints lib "UIKit.framework" selector "removeConstraints:" (obj_id as ptr, constraints as ptr) Declare function constraints lib "UIKit.framework" selector "constraints" (obj_id as ptr) as ptr dim ctrs As ptr = constraints(screen.handle) removeConstraints(screen.Handle, ctrs) End Sub
Sub RemoveConstraintsXC(extends container As MobileUIControl) // http://stackoverflow.com/questions/13388104/remove-auto-layout-constraints-for-specific-object '[detailsPhotoView removeConstraints:detailsPhotoView.constraints]; Declare sub removeConstraints lib "UIKit.framework" selector "removeConstraints:" (obj_id as ptr, constraints as ptr) Declare function constraints lib "UIKit.framework" selector "constraints" (obj_id as ptr) as ptr dim ctrs As ptr = constraints(container.Handle) removeConstraints(container.Handle, ctrs) End Sub
Sub SetActivityIndicatorViewStyleXC(extends progress As MobileProgressWheel, value As UIActivityIndicatorViewStyle) #if TargetIOS declare sub setActivityIndicatorViewStyle lib "UIKit.framework" selector "setActivityIndicatorViewStyle:" (id as ptr, value as UIActivityIndicatorViewStyle) setActivityIndicatorViewStyle progress.Handle, value #endif End Sub
Sub SetAlphaValueXC(extends ctrl As MobileUIControl, value As Double) Declare Sub setAlphaValue Lib "UIKit.framework" selector "setAlpha:" (id As ptr, value As CGFloat) setAlphaValue ctrl.handle, value End Sub
Sub SetBackgroundColorXC(extends ctrl As MobileUIControl, value As Color) Dim uic As UIKit.UIColor If value.Alpha = 255 Then uic = UIKit.UIColor.ClearColor else uic = New UIKit.UIColor(value) end if Declare Sub decl_SetBackgroundColor lib "UIKit.framework" selector "setBackgroundColor:" (aUIView As Ptr, aUIColor As Ptr) ' Here is the corresponding Xojo call decl_SetBackgroundColor(ctrl.handle, uic) End Sub
Sub SetCornersRadiusXC(extends view As UIKit.UIView, corners As Integer, radius As Double) #If Not DebugBuild // Create the path (with only the top-left corner rounded) 'UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:imageView.bounds 'byRoundingCorners:UIRectCornerTopLeft 'cornerRadii:CGSizeMake(10.0, 10.0)]; // Create the shape layer and set its path 'CAShapeLayer *maskLayer = [CAShapeLayer layer]; 'maskLayer.frame = imageView.bounds; 'maskLayer.path = maskPath.CGPath; // Set the newly created shape layer as the mask for the image view's layer 'imageView.layer.mask = maskLayer; Declare Function layer_ Lib "UIKit.framework" selector "layer" (id As ptr) As Ptr Declare Function bezierPathWithRoundedRect Lib "UIKit.framework" selector "bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:" _ (cls_ref as ptr, bounds as CGRect, corners as Integer, radius as CGSize) as ptr Dim radSize As CGSize radSize.width = radius radSize.height = radius Dim bounds As Xojo.Core.Rect = view.bounds Dim boundRect As CGRect = CGRectMake(bounds.left, bounds.Top, bounds.Width, bounds.Height) Dim maskPath As Ptr maskPath = bezierPathWithRoundedRect(Foundation.NSClassFromString("UIBezierPath"), _ boundRect, corners, radSize) Dim maskLayer As Ptr maskLayer = layer_(NSClassFromString("CAShapeLayer")) Declare Sub setFrame_ Lib "UIKit.framework" selector "setFrame:" (obj_id As ptr, frame As CGRect) setFrame_(maskLayer, boundRect) Declare Sub setPath_ Lib "UIKit.framework" selector "setPath:" (obj_id As ptr, path As ptr) Declare function CGPath_ lib "UIKit.framework" selector "CGPath" (obj_id as ptr) as ptr setPath_(maskLayer, CGPath_(maskPath)) Dim layer As ptr = layer_(view.id) Declare Sub setMask Lib "UIKit.framework" selector "setMask:" (obj_id As ptr, mask As ptr) setMask(layer, maskLayer) Declare Sub masksToBounds_ Lib "UIKit.framework" selector "setMasksToBounds:" (id As ptr, value As Boolean) 'masksToBounds_(layer, False) #EndIf End Sub
Sub SetDatePickerMinuteIntervalXC(Extends datepicker As MobileDateTimePicker, interval As Integer) Declare Sub minuteInterval Lib "UIKit.framework" Selector "setMinuteInterval:" (obj As ptr, interval As Integer) minuteInterval(datepicker.Handle, interval) End Sub
Sub SetDatePickerStyleXC(extends datepicker As MobileDateTimePicker, style As ControlExtensionsXC.UIDatePickerStyle) if ExtensionsXC.GetiOSVersionXC >= 13.4 then declare sub preferredDatePickerStyle lib "UIKit.framework" selector "setPreferredDatePickerStyle:" (obj as ptr, mode as UIDatePickerStyle) preferredDatePickerStyle(datepicker.Handle, style) end if End Sub
Sub SetOnTintColorXC(extends switch As MobileSwitch, value As Color) 'declare sub setTintColor lib "UIKit.framework" selector "setTintColor:" (id as ptr, UIColor as Ptr) 'setTintColor s.Handle, new UIColor(c) Dim uic As UIKit.UIColor If value.Alpha = 255 Then uic = UIKit.UIColor.ClearColor Else uic = New UIColor(value) End If declare sub setOnTintColor lib "UIKit.framework" selector "setOnTintColor:" (id as ptr, UIColor as Ptr) setOnTintColor(switch.Handle, uic) End Sub
Sub SetOverrideUserInterfaceStyleXC(extends control As MobileUIControl, style As ControlExtensionsXC.UIUserInterfaceStyle) if ExtensionsXC.GetiOSVersionXC >= 13.0 then declare sub overrideUserInterfaceStyle lib "UIKit.framework" selector "setOverrideUserInterfaceStyle:" (obj as ptr, style As ControlExtensionsXC.UIUserInterfaceStyle) overrideUserInterfaceStyle(control.Handle, style) end if End Sub
Sub SetTextColorXC(extends picker as MobileDateTimePicker, value as Color) Dim uic As UIKit.UIColor If value.Alpha = 255 Then uic = UIKit.UIColor.ClearColor else uic = New UIKit.UIColor(value) end if declare sub setValue_ lib "Foundation" selector "setValue:forKey:" (obj_id as ptr, value as ptr, key as CFStringRef) setValue_(picker.Handle, uic, "textColor") End Sub
Sub SetTintColorXC(extends ctrl As MobileUIControl, c As Color) declare sub setTintColor lib "UIKit.framework" selector "setTintColor:" (id as ptr, UIColor as Ptr) setTintColor ctrl.Handle, new UIColor(c) End Sub
Sub SetUIFontXC(extends lbl as MobileLabel, fontHandle as ptr) Declare sub setFont_ lib "UIKit.framework" selector "setFont:" (obj as ptr, font as ptr) setFont_(lbl.Handle, fontHandle) End Sub
Sub SetUserInterfaceStyleXC(extends ctrl as MobileUIControl, value as ControlExtensionsXC.UIUserInterfaceStyle) if ExtensionsXC.GetiOSVersionXC >= 13.4 then Declare sub overrideUserInterfaceStyle lib "UIKit" selector "setOverrideUserInterfaceStyle:" (obj as ptr, value as UIUserInterfaceStyle) overrideUserInterfaceStyle(ctrl.handle, value) end if End Sub
Sub StretchToParentXC(extends c As MobileUIControl, parentView As MobileUIControl) Dim cons As iOSLayoutConstraint //Top cons = new iOSLayoutConstraint(c, _ iOSLayoutConstraint.AttributeTypes.top, _ iOSLayoutConstraint.RelationTypes.Equal, _ parentView, _ iOSLayoutConstraint.AttributeTypes.Top, _ 1, _ 0) cons.Active = True parentView.AddConstraint(cons) //Left cons = new iOSLayoutConstraint(c, _ iOSLayoutConstraint.AttributeTypes.left, _ iOSLayoutConstraint.RelationTypes.Equal, _ parentView, _ iOSLayoutConstraint.AttributeTypes.left, _ 1, _ 0) cons.Active = True parentView.AddConstraint(cons) //Right cons = new iOSLayoutConstraint(c, _ iOSLayoutConstraint.AttributeTypes.Right, _ iOSLayoutConstraint.RelationTypes.Equal, _ parentView, _ iOSLayoutConstraint.AttributeTypes.Right, _ 1, _ 0) cons.Active = True parentView.AddConstraint(cons) //Bottom cons = new iOSLayoutConstraint(c, _ iOSLayoutConstraint.AttributeTypes.Bottom, _ iOSLayoutConstraint.RelationTypes.Equal, _ parentView, _ iOSLayoutConstraint.AttributeTypes.Bottom, _ 1, _ 0) cons.Active = True parentView.AddConstraint(cons) End Sub
Sub StretchToViewXC(extends c As MobileUIControl, parentView As MobileScreen) Dim cons As iOSLayoutConstraint //Top cons = new iOSLayoutConstraint(c, _ iOSLayoutConstraint.AttributeTypes.top, _ iOSLayoutConstraint.RelationTypes.Equal, _ parentView, _ iOSLayoutConstraint.AttributeTypes.Top, _ 1, _ 0) cons.Active = True parentView.AddConstraint(cons) //Left cons = new iOSLayoutConstraint(c, _ iOSLayoutConstraint.AttributeTypes.left, _ iOSLayoutConstraint.RelationTypes.Equal, _ parentView, _ iOSLayoutConstraint.AttributeTypes.left, _ 1, _ 0) cons.Active = True parentView.AddConstraint(cons) //Right cons = new iOSLayoutConstraint(c, _ iOSLayoutConstraint.AttributeTypes.Right, _ iOSLayoutConstraint.RelationTypes.Equal, _ parentView, _ iOSLayoutConstraint.AttributeTypes.Right, _ 1, _ 0) cons.Active = True parentView.AddConstraint(cons) //Bottom cons = new iOSLayoutConstraint(c, _ iOSLayoutConstraint.AttributeTypes.Bottom, _ iOSLayoutConstraint.RelationTypes.Equal, _ parentView, _ iOSLayoutConstraint.AttributeTypes.Bottom, _ 1, _ 0) cons.Active = True parentView.AddConstraint(cons) End Sub
End Module
Module LayerExtensionsXC
Const QuartzCoreLib = Quartzcore.framework
Function GetLayerXC(extends c as MobileUIControl) As ptr Declare Function layer_ Lib "UIKit.framework" selector "layer" (id As ptr) As Ptr Dim layer As ptr = layer_(c.Handle) Return layer End Function
Function SetBackgroundGradientXC(extends ctrl As MobileUIControl, linearBrush As LinearGradientBrush) As Ptr Dim layer as ptr = ctrl.GetLayerXC Declare Function init Lib "Foundation.framework" selector "init" (obj_id As ptr) As ptr Declare Function alloc Lib "Foundation.framework" selector "alloc" (clsRef As ptr) As ptr Declare Function NSClassFromString Lib "Foundation.framework" (clsName As CFStringRef) As ptr Dim gradient As ptr = init(alloc(NSClassFromString ("CAGradientLayer"))) ' gradient.frame = view.bounds; Dim frame As ExtensionsXC.xcCGRect Dim viewFrame As Rect = ctrl.GetFrameXC frame.origin.x = 0 frame.origin.y = 0 frame.rsize.width = viewFrame.Width frame.rsize.height = viewFrame.Height #if False linearBrush = New LinearGradientBrush linearBrush.StartPoint = New Point(0, 0) linearBrush.EndPoint = New Point(sz.Width, sz.Height) linearBrush.GradientStops.Add(New Pair(0, &c6078EA)) linearBrush.GradientStops.Add(New Pair(1.0, &cFD575C)) #endif Declare Sub setFrame Lib UIKitLib selector "setFrame:" (obj_id As ptr, frame As ExtensionsXC.xcCGRect) setFrame(gradient, frame) ' gradient.colors = @[(id)[UIColor whiteColor].CGColor, (id)[UIColor blackColor].CGColor]; Declare Function arrayWithCapacity Lib "Foundation" selector "arrayWithCapacity:" (cls As ptr, count as UInteger) As ptr Declare Sub addObject Lib "Foundation" selector "addObject:" (arr As ptr, obj As ptr) Dim colorArray As ptr colorArray = arrayWithCapacity(NSClassFromString("NSMutableArray"), 2) Dim c1, c2 As UIKit.UIColor Dim col1 As color = linearBrush.GradientStops(0).Right Dim col2 As color = linearBrush.GradientStops(linearBrush.GradientStops.LastIndex).Right c1 = New UIKit.UIColor(col1) c2 = New UIKit.UIColor(col2) addObject colorArray, c1.CGColor addObject colorArray, c2.CGColor Declare Sub setColors Lib QuartzCoreLib selector "setColors:" (obj_id As ptr, colors As ptr) setColors(gradient, colorArray) Dim startPt As ExtensionsXC.xcCGPoint StartPt.x = linearBrush.StartPoint.X StartPt.y = linearBrush.StartPoint.Y Dim endPt As ExtensionsXC.xcCGPoint endPt.x = linearBrush.EndPoint.X endPt.y = linearBrush.EndPoint.Y Declare sub startPoint lib QuartzCoreLib selector "setStartPoint:" (obj as ptr, value as ExtensionsXC.xcCGPoint) startPoint(gradient, startpt) Declare sub endPoint lib QuartzCoreLib selector "setEndPoint:" (obj as ptr, value as ExtensionsXC.xcCGPoint) endPoint(gradient, endpt) 'Declare Sub clipsToBounds Lib "UIKit.framework" selector "setMasksToBounds:" (id As ptr, value As Boolean) 'clipsToBounds(gradient, True) ' 'Declare Sub setCornerRadius Lib "QuartzCore.framework" selector "setCornerRadius:" (id As ptr, value As CGFloat) ' 'setCornerRadius gradient, 16 ' [view.layer insertSublayer:gradient atIndex:0]; Declare Sub insertSublayer Lib QuartzCoreLib selector "insertSublayer:atIndex:" (id As ptr, aLayer As ptr, Index As UInt32) Declare Sub replaceSubLayer Lib QuartzCoreLib selector "replaceSublayer:with:" (id As ptr, aLayer As ptr, aLayer2 as ptr) 'if gradientSet = False then insertSublayer layer, gradient, 0 'Else 'replaceSubLayer(layer, lastLayer, gradient) 'End If Return gradient End Function
Sub SetBorderColorXC(extends c As MobileUIControl, value As Color) Dim layer as ptr = c.GetLayerXC Dim uic As uikit.uicolor If value.Alpha = 255 Then uic = UIKit.UIColor.ClearColor Else uic = New UIColor(value) End If declare sub setBorderColor lib "UIKit.framework" selector "setBorderColor:" (obj_id as ptr, col as ptr) setBorderColor(layer, uic.CGColor) End Sub
Sub SetBorderWidthXC(extends c As MobileUIControl, width As Double) Dim layer As ptr = c.GetLayerXC declare sub setBorderWidth lib "UIKit.framework" selector "setBorderWidth:" (obj_id as ptr, value as CGFloat) setBorderWidth(layer, width) End Sub
Sub SetCornerRadiusXC(extends ctrl As MobileUIControl, radius As Double) Declare Function layer_ Lib "UIKit.framework" selector "layer" (id As ptr) As Ptr Dim layer As ptr = layer_(ctrl.Handle) Declare Sub setCornerRadius Lib "QuartzCore.framework" selector "setCornerRadius:" (id As ptr, value As CGFloat) setCornerRadius layer, radius if ctrl isa MobileButton then Dim insets As ExtensionsXC.xcUIEdgeInsets insets.Left = radius insets.Top = 0 insets.Right = radius insets.Bottom = 0 MobileButton(ctrl).SetButtonInsetsXC(insets) else Declare Sub clipsToBounds Lib "UIKit.framework" selector "setClipsToBounds:" (id As ptr, value As Boolean) clipsToBounds(ctrl.Handle, True) end if End Sub
Sub SetShadowXC(extends control As MobileUIControl, ShadowColor As Color, radius As Double, offset As Point, opacity As Double = 1.0) Declare Function layer_ Lib "UIKit.framework" selector "layer" (id As ptr) As Ptr Dim layer As ptr = layer_(control.Handle) Declare Sub masksToBounds_ Lib "UIKit.framework" selector "setMasksToBounds:" (id As ptr, value As Boolean) masksToBounds_(layer, False) Declare Sub shadowColor_ Lib QuartzCoreLib selector "setShadowColor:" (id As ptr, col As ptr) Dim c As new UIColor(ShadowColor) shadowColor_(layer, c.CGColor) Declare Sub shadowRadius_ Lib QuartzCoreLib selector "setShadowRadius:" (id As ptr, col As CGFloat) shadowRadius_(layer, radius) Dim size As ExtensionsXC.xcCGSize size.width = offset.X size.height = offset.y Declare Sub shadowOffset_ Lib QuartzCoreLib selector "setShadowOffset:" (id As ptr, sz As ExtensionsXC.xcCGSize) shadowOffset_(layer, size) 'Declare function opac lib QuartzCoreLib selector "shadowOpacity" (id as ptr) as CGFloat 'dim v As Double = opac(layer) 'v = v Declare Sub shadowOpacity_ Lib QuartzCoreLib selector "setShadowOpacity:" (id As ptr, col As single) shadowOpacity_(layer, opacity) End Sub
End Module
Module ExtensionsXC
Const kUseUIKit = False
Const kVersion = 2.6.0
Protected Function CGRectMake(x As CGFloat, y As CGFloat, width As CGFloat, height As CGFloat) As xcCGRect Dim origin As ExtensionsXC.xcCGPoint origin.x = x origin.y = y Dim size As ExtensionsXC.xcCGSize size.width = width size.height = height Dim rect As xcCGRect rect.origin = origin rect.rsize = size Return rect End Function
Protected Function GetiOSVersionAsStringXC() As String Static sSystemVersion As String //Get sSystemVersion only once If sSystemVersion.IsEmpty then Declare Function currentDevice_ Lib "UIKit.framework" selector "currentDevice" (clsRef As ptr) As ptr Declare Function systemversion_ Lib "UIKit.framework" selector "systemVersion" (obj_id As ptr) As CFStringRef Declare Function NSClassFromString Lib "Foundation" (name As CFStringRef) As Ptr Dim device As Ptr = currentDevice_(NSClassFromString("UIDevice")) Dim systemVersion As String = systemversion_(device) sSystemVersion = systemVersion End If Return sSystemVersion End Function
Protected Function GetiOSVersionXC() As Double Static sSystemVersion As Double //Get sSystemVersion only once If sSystemVersion = 0.0 Then Declare Function currentDevice_ Lib "UIKit.framework" selector "currentDevice" (clsRef As ptr) As ptr Declare Function systemversion_ Lib "UIKit.framework" selector "systemVersion" (obj_id As ptr) As CFStringRef Declare Function NSClassFromString Lib "Foundation" (name As CFStringRef) As Ptr Dim device As Ptr = currentDevice_(NSClassFromString("UIDevice")) Dim systemVersion As String = systemversion_(device) Try sSystemVersion = Double.FromString(systemVersion) Catch End Try End If Return sSystemVersion End Function
Protected Function IsTestflightXC() As Boolean Declare Function mainBundle Lib "Foundation" selector "mainBundle" (clsRef As ptr) As ptr Declare Function NSClassFromString Lib "Foundation" (name As CFStringRef) As Ptr Declare Function appStoreReceiptURL lib "Foundation" selector "appStoreReceiptURL" (obj as ptr) as ptr Declare function path lib "Foundation" selector "path" (obj as ptr) as CFStringRef Dim theURL As Ptr = appStoreReceiptURL(mainBundle(NSClassFromString("NSBundle"))) if theURL <> nil then Dim receiptURLString as Text = path(theURL) if receiptURLString.IndexOf("sandboxReceipt") > -1 then Return True end if end if End Function
Protected Function LoadConstantXC(frameworkName as String, constName as String) As Ptr Declare Function dlsym Lib "/usr/lib/libSystem.dylib" ( handle As Ptr, name As CString ) As ptr dim libPtr as Ptr = LoadFrameworkXC(frameworkName) Dim cstr As CString = constName dim constPtr as Ptr = dlsym(libPtr, cstr) Return constPtr Return nil End Function
Protected Function LoadFrameworkXC(frameworkName as String) As Ptr static frameworkHandlesDict as Dictionary = new Dictionary if frameworkHandlesDict.HasKey(frameworkName) then Return frameworkHandlesDict.Value(frameworkName) Declare Function dlopen Lib "/usr/lib/libSystem.dylib" ( path As CString, mode As Int32 ) As Ptr Declare Function dlerror Lib "/usr/lib/libSystem.dylib" () As CString Const RTLD_LAZY = 1 Const RTLD_GLOBAL = 8 dim path as String = "/System/Library/Frameworks/" + frameworkName + ".framework/" + frameworkName Dim pathCstr As CString = path Dim result As ptr = dlopen(pathCstr, RTLD_LAZY Or RTLD_GLOBAL ) If result = Nil Then 'Dim reason As Text = Text.FromCString(dlerror(), Xojo.Core.TextEncoding.UTF8) Dim reason As String = dlerror Dim exc As New InvalidArgumentException exc.message = reason Raise exc Return nil end if frameworkHandlesDict.Value(frameworkName) = result Return result End Function
Protected Function MainScreenScaleXC() As Double //declare function NSClassFromString lib "Foundation.Framework" (aClassName as CFStringRef) as Ptr Declare Function NSClassFromString Lib "Foundation" (aClassName As CFStringRef) As Ptr Soft Declare Function scale Lib "UIKit" selector "scale" (classRef As Ptr) As CGFloat Soft Declare Function mainScreen Lib "UIKit" selector "mainScreen" (classRef As Ptr) As ptr Dim scale As Double = scale(mainScreen(NSClassFromString("UIScreen"))) Return scale End Function
Protected Function MainScreenSizeXC() As Size //declare function NSClassFromString lib "Foundation.Framework" (aClassName as CFStringRef) as Ptr Declare Function NSClassFromString Lib "Foundation" (aClassName As CFStringRef) As Ptr //Improve size of picture Declare Function mainScreen Lib UIKitLib selector "mainScreen" (clsRef As ptr) As ptr Declare Function nativebounds Lib UIKitLib selector "nativeBounds" (obj_id As Ptr) As xcCGRect Dim sz As xcCGSize = nativeBounds(mainScreen(NSClassFromString("UIScreen"))).rsize Dim s As new Size(sz.width, sz.height) Return s End Function
Protected Function StringConstantXC(frameworkName as String, constName as String) As String Dim constPtr As Ptr = LoadConstantXC(frameworkName, constName) if constPtr <> nil then Return constPtr.CFStringRef(0) end if Return "" End Function
Protected Function UIColorFromColor(value as color) As ptr Soft Declare Function colorWithRGBA Lib "UIKit" Selector "colorWithRed:green:blue:alpha:" (UIColorClassRef As Ptr, red As CGFloat, green As CGFloat, blue As CGFloat, alpha As CGFloat) As Ptr Soft Declare Function NSClassFromString Lib "Foundation" (classname As CFStringRef) As Ptr static UIColorClassPtr As Ptr = NSClassFromString("UIColor") Dim c as color = value Dim red As CGFloat = c.red / 255 Dim green As CGFloat = c.Green / 255 Dim blue As CGFloat = c.Blue / 255 Dim alpha As CGFloat = 1.0 - c.Alpha / 255 Dim colorPtr As ptr = colorWithRGBA(UIColorClassPtr, red, green, blue, alpha) Return colorPtr End Function
Protected Function UIEdgeInsetMake(top As CGFloat, left As CGFloat, bottom As CGFloat, right As CGFloat) As xcUIEdgeInsets Dim insets As xcUIEdgeInsets insets.Top = top insets.Left = Left insets.Bottom = bottom insets.Right = Right Return insets End Function
Sub UseDefaultSoundXC(extends content As NotificationContent) //new in version 2.0.1 Declare Function defaultSound lib "UserNotifications" selector "defaultSound" (obj as ptr) as ptr declare function NSClassFromString lib "Foundation" (clsName as CFStringRef) as ptr declare sub setSound lib "UserNotifications" Selector "setSound:" (obj as ptr, snd as ptr) setSound(content.Handle, defaultSound(NSClassFromString("UNNotificationSound"))) End Sub
Note "History"
## History ### Version 2.6 - Released 2025-02-12 * New TabbarExtensionsXC.SetTabBarTitleXC * New MapViewerExtensionsXC * New ControlExtensionsXC.SetBackgroundGradientXC * New TabbarExtensionsXC.SetTabBarUnselectedColorXC * New TableExtensionsXC.SetAllowsSelectionDuringEditingXC ### Version 2.5.3 - Released 2025-02-03 * New TextFieldExtensionsXC.AddDoneToolbarButtonXC (for TextField) ### Version 2.5.2 - Released 2024-12-07 * New ViewExtensionsXC.SetOverrideUserInterfaceStyleXC method * New ControlExtensionsXC.SetOverrideUserInterfaceStyleXC method ### Version 2.5.1 - Released 2024-07-16 * New TextFieldExtensionsXC.AddDoneToolbarButtonXC (for TextArea) ### Version 2.5 - Released 2024-07-08 * New TableExtensions.SelectRowXC metho * New AppExtensionsXC.idleTimerDisabled property ### Version 2.4.2 - Released 2024-02-14 * New SplitViewExtensionsXC module for iOSSplitView * Fixed a few methods ### Version 2.4 - Released 2024-01-09 * New AppExtensionsXC.SetBrightnessXC * Fixed a few methods especially SetNavBarTitleColorXC and SetNavBarTintColorXC ### Version 2.3 - Released 2022-12-14 * Updated for Xojo 2022r4 ### Version 2.2 - Released 2022-07-14 * New ViewExtensionsXC.TransitionWithViewDurationOptionsXC * New ViewExtensionsXC.AnimateWithDurationXC * New ViewExtensionsXC.LayoutIfNeededXC * New ControlExtensionsXC.SetUserInterfaceStyleXC * New ImageExtensionsXC.SaveToCameraRollXC ### Version 2.1.2 - Released 2022-02-02 * New iOSMobileTable.SetScrollbarVisibleXC * New iOSMobileTable.SetSectionHeaderTopPaddingXC * New MobileScrollableArea.SetHorizontalScrollbarVisibleXC * New MobileScrollableArea.SetVerticalScrollbarVisibleXC ### Version 2.1.1 - Released 2022-02-01 * Fixed MobileScreen.SetNavBarTitleColorXC * Fixed MobileScreen.PushToHideTabBarXC ### Version 2.1 - Released 2022-01-09 * New MobileScreen.ShowSheetXC * New SliderExtensionsXC * New MobileScreen.SetPreferredContentSizeXC method * Updated MobileLabel.AdjustsFontForContentSizeCategoryXC to allow for custom fonts ### Version 2.0.5 - Released 2021-10-26 * New MobileLabel.AdjustsFontForContentSizeCategoryXC * New MobileButton.AdjustsFontForContentSizeCategoryXC * Fixed MobileUIControl.SetAlphaValueXC ### Version 2.0.4 - Released 2021-09-28 * Fixed MobileScreen.SetNavBarTitleImageXC * New example for MobileScreen.SetNavBarTitleImageXC * Updated HTMLViewerExtensionsXC.ExecuteJavascriptXC to use a Variant * Improved HTMLViewer example ### Version 2.0.3 - Released 2021-09-26 ** Fixed Me.SetBackgroundColorXC(aColorGroup) ** Fixed Me.SetBorderColorXC(aColorGroup) ** Fixed some deprecations ### Version 2.0.2 - Released 2021-09-17 ** New TableSearchExtensionsXC module ** Added iOSMobileTable.GetSearchFilterIndexXC ** Added iOSMobileTable.SetSearchActiveXC ** Added iOSMobileTable.SetSearchFieldTextColorXC (iOS13+) ** Added iOSMobileTable.SetSearchFiltersXC ### Version 2.0.1 - Released 2021-04-20 ** Added NotificationContent.UseDefaultSoundXC ### Version 2.0 - Released 2021-04-15 * Now compatible with Xojo 2020r2+ (iOS Framework API 2) ** Added MobileButton.SetRoleXC ** Added MobileDateTimePicker.SetDatePickerStyleXC ** Added MobileTableCellData.SetTextAlignmentXC ** Added MobileScreen.SetNavBarTintColorXC ** Added MobileScreen.SetNavBarTranslucentXC ** Added MobileScreen.PushToSafariControllerXC ### Version 1.?? - Released 2020-?? * Added iOSDatePicker.SetTextColorXC ### Version 1.7.0 - Released 2019-11-19 * New ImageExtensionsXC module ### Version 1.6.0 - Released 2019-04-06 * New iOSView hidekeyboard * Fix iOSControl.SetAlphaValueXC for iOS 12.2 (Requires iOSKit) ### Version 1.5.1 - Released 2019-02-21 * New HTMLViewer Function LoadFileXC * New iOSView Function isRightToLeftXC * Version 1.5.0 - Released 2019-01-31 ** Added Layer Extensions 1. Border Color 2. Border Width 3. Corner Radius 4. Shadow * Version 1.4.0 - Released 2018-08-15 ** Added HTMLViewer Extensions 1. ExecuteJavascript 2. LoadPage 3. UserAgent ** Added TableExtensionsXC.SetSeparatorColorXC * Version 1.3.1 - Released 2018-05-30 ** Added iOSView.SetToolBarBackgroundColorXC and ** Added iOSView.SetToolBarColorXC * Version 1.3.1 - Released 2018-05-30 ** Added App.SetWindowColorXC * Version 1.3 - Released 2018-05-27 ** Added scrolling functions to iOSTextArea * Version 1.2 - Released 2018-05-?? ** Added an app icon ** Fixed GetBoundsXC function ** Renamed ScrollViewExtensionsXCXC to ScrollViewExtensionsXC ** Removed Modal Curl transition ** AdjustFontSizeToFitWidthXC now has an optional lines property to set the amount of lines to display ** SetTabPageXC to set the current page in a TabBar view ** GetTabPageXC to get the current page index in a TabBar view ** SetNavBarTitleColorXC to set the color of the text in the navbar ** GetiOSVersionXC returns the current iOS version number ** Table.GetScrollPositionXC returns the current section/row position * Version 1.1 - Released 2018-05-10 ** New modal transition options * Version 1.0 - Released 2018-04-26 Copy-paste the iOSDesignExtensions folder into your project. Most controls will then have additional methods, all ending with "XC" Contact: https://www.jeremieleroy.com/contact.php Feel free to ask for feature requests! Made with ❤️ in France Jeremie LEROY
Structure xcCGAffineTransform a as CGFloat b as CGFloat c as CGFloat d as CGFloat tx as CGFloat ty as CGFloat End Structure
Structure xcCGPoint x As CGFloat y as CGFloat End Structure
Structure xcCGRect origin As xcCGPoint rsize as xcCGSize End Structure
Structure xcCGSize width As CGFloat height As CGFloat End Structure
Structure xcUIEdgeInsets Top as CGFloat Left As CGFloat Bottom As CGFloat Right As CGFloat End Structure
End Module
Module ScrollViewExtensionsXC
Enum UIScrollViewIndicatorStyle default = 0 black white End Enum
Sub FlashScrollIndicatorsXC(extends scroll As MobileScrollableArea) Declare Sub flashScrollIndicators_ Lib "UIKit.framework" selector "flashScrollIndicators" (obj_id As ptr) flashScrollIndicators_(scroll.Handle) End Sub
Function ScrollPositionXC(extends scroll As MobileScrollableArea) As Point Dim offset As point Declare Function ContentOffset_ Lib "UIKit.framework" selector "contentOffset" (obj_id As ptr) As ExtensionsXC.xcCGPoint Dim pt As ExtensionsXC.xcCGPoint = ContentOffset_(scroll.Handle) offset = New Point(pt.x, pt.y) Return offset End Function
Sub ScrollToXC(extends scroll As MobileScrollableArea, point As Point, animated As Boolean = True) Declare Sub setContentOffsetAnimated Lib "UIKit.framework" selector "setContentOffset:animated:" (id As ptr, value As ExtensionsXC.xcCGPoint, animated As Boolean) Dim pt As ExtensionsXC.xcCGPoint pt.x = point.X pt.y = point.Y setContentOffsetAnimated(scroll.Handle, pt, animated) End Sub
Sub SetBouncesXC(extends scroll As MobileScrollableArea, value As Boolean) declare sub bounces_ lib "UIKit.framework" selector "setBounces:" (obj_id as ptr, value as Boolean) bounces_(scroll.handle, value) End Sub
Sub SetHorizontalScrollbarVisibleXC(extends scroll as MobileScrollableArea, value as Boolean) //Hide scrollbar Declare Sub setScrollIndicator lib "UIKit.framework" selector "setShowsHorizontalScrollIndicator:" (id as ptr, value as Boolean) setScrollIndicator scroll.Handle, value End Sub
Sub SetIndicatorStyleXC(extends scroll as MobileScrollableArea, value as ScrollViewExtensionsXC.UIScrollViewIndicatorStyle) Declare Sub setIndicatorStyle_ Lib "UIKit.framework" selector "setIndicatorStyle:" (obj_id As ptr, value As ScrollViewExtensionsXC.UIScrollViewIndicatorStyle) setIndicatorStyle_(scroll.Handle, value) End Sub
Sub SetPagingEnabledXC(extends scroll As MobileScrollableArea, value As Boolean) Declare Sub setPagingEnabled lib "UIKit.framework" selector "setPagingEnabled:" (id as ptr, value as Boolean) setPagingEnabled scroll.Handle, value End Sub
Sub SetScrollEnabledXC(extends scroll As MobileScrollableArea, value As Boolean) Declare Sub scrollEnabled Lib "UIKit.framework" selector "setScrollEnabled:" (obj_id As ptr, value As Boolean) scrollenabled(scroll.Handle, value) End Sub
Sub SetScrollsToTopXC(extends scroll As MobileScrollableArea, value As Boolean) Declare Sub scrollsToTop_ Lib "UIKit.framework" selector "setScrollsToTop:" (obj_id As ptr, value As Boolean) scrollsToTop_(scroll.Handle, value) End Sub
Sub SetVerticalScrollbarVisibleXC(extends scroll as MobileScrollableArea, value as Boolean) //Hide scrollbar Declare Sub setScrollIndicator lib "UIKit.framework" selector "setShowsVerticalScrollIndicator:" (id as ptr, value as Boolean) setScrollIndicator scroll.Handle, value End Sub
End Module
Module SegmentedControlExtensionsXC
Enum UIControlState Normal = 0 Highlighted = 1 Disabled = 2 Selected = 4 End Enum
Sub AdjustFontSizeToFitWidthXC(extends seg As MobileSegmentedButton) //Requires UIKit #If ExtensionsXC.kUseUIKit Dim subViews As Foundation.NSArray Declare Function getSubviews Lib "UIKit.framework" selector "subviews" (id As ptr) As ptr Declare Function isKindOfClass Lib "UIKit.framework" selector "isKindOfClass:" (obj_id As ptr, cls As ptr) As Boolean Declare Sub setAdjustsFontSizeToFitWidth Lib "UIKit.framework" selector "setAdjustsFontSizeToFitWidth:" (id As ptr, value As Boolean) subViews = New Foundation.NSArray(getSubviews(seg.Handle)) For i As Integer = 0 To subViews.Count-1 Dim view As ptr = subViews.Value(i) Dim subSubViews As Foundation.NSArray subSubViews = New Foundation.NSArray(getSubviews(view)) For j As Integer = 0 To subSubViews.Count-1 Dim view2 As ptr = subSubViews.Value(j) If isKindOfClass(view2, Foundation.NSClassFromString("UILabel")) Then setAdjustsFontSizeToFitWidth(view2, True) End If Next Next #else #Pragma Unused seg #EndIf End Sub
Private Function ImageWithColor(c As UIKit.UIColor) As ptr // create a 1x1 image with this color Declare Sub UIGraphicsBeginImageContext Lib "UIKit.framework" (mSize As ExtensionsXC.xcCGSize) Declare Function UIGraphicsGetCurrentContext Lib "UIKit.framework" As ptr Declare Sub CGContextSetFillColorWithColor Lib "CoreGraphics.framework" (context As ptr, Color As ptr) Declare Sub CGContextFillRect Lib "CoreGraphics.framework" (context As ptr, rect As ExtensionsXC.xcCGRect) Declare Function UIGraphicsGetImageFromCurrentImageContext Lib "UIKit.framework" As ptr Declare Sub UIGraphicsEndImageContext Lib "UIKit.framework" Dim rect As ExtensionsXC.xcCGRect Dim pt As ExtensionsXC.xcCGPoint Dim sz As ExtensionsXC.xcCGSize sz.width = 1.0 sz.height = 1.0 rect.origin = pt rect.rsize = sz UIGraphicsBeginImageContext(rect.rsize) Dim context As ptr = UIGraphicsGetCurrentContext CGContextSetFillColorWithColor(context, c.CGColor) CGContextFillRect(context, rect) Dim newUIImage As Ptr = UIGraphicsGetImageFromCurrentImageContext UIGraphicsEndImageContext Return newUIImage 'Private func imageWithColor(color: UIColor) -> UIImage { 'let rect = CGRectMake(0.0, 0.0, 1.0, 1.0) 'UIGraphicsBeginImageContext(rect.size) 'let context = UIGraphicsGetCurrentContext 'CGContextSetFillColorWithColor(context, Color.CGColor); 'CGContextFillRect(context, rect); 'let image = UIGraphicsGetImageFromCurrentImageContext; 'UIGraphicsEndImageContext; 'Return image '} End Function
Sub SetNormalColorXC(extends seg As MobileSegmentedButton, c As color) Declare Sub setBackgroundImage_ Lib "UIKit.framework" selector "setBackgroundImage:forState:barMetrics:" (obj_id As ptr, image As ptr, state As UIControlState, barMetrics As Integer) setBackgroundImage_(seg.Handle, imageWithColor(new UIColor(c)), UIControlState.Normal, 0) End Sub
Sub SetRemoveBordersXC(extends seg As MobileSegmentedButton) Declare Sub setDividerImage Lib "UIKit.framework" selector "setDividerImage:forLeftSegmentState:rightSegmentState:barMetrics:" _ (obj_id As ptr, image As ptr, leftSegmentState As UIControlState, rightSegmentState As UIControlState, barMetrics As Integer) setDividerImage(seg.Handle, ImageWithColor(UIColor.ClearColor), UIControlState.Normal, UIControlState.Normal, 0) End Sub
Sub SetSelectedColorXC(extends seg as MobileSegmentedButton, c as color) Declare Sub setBackgroundImage_ Lib "UIKit.framework" selector "setBackgroundImage:forState:barMetrics:" (obj_id As ptr, image As ptr, state As UIControlState, barMetrics As Integer) setBackgroundImage_(seg.Handle, imageWithColor(New UIColor(c)), UIControlState.Selected, 0) End Sub
Sub SetTextColorXC(extends seg As MobileSegmentedButton, c As color, state As SegmentedControlExtensionsXC.UIControlState) #If ExtensionsXC.kUseUIKit Dim constStr As Text = Foundation.StringConstant("UIKit", "NSForegroundColorAttributeName") Dim constPtr As new NSString(constStr) Dim nsDic As Foundation.NSDictionary nsDic = Foundation.NSDictionary.CreateFromObject(constPtr, New UIColor(c)) Declare Sub setTitleTextAttributes Lib "UIKit" selector "setTitleTextAttributes:forState:" _ (obj_id As ptr, att As ptr, state As UIControlState) setTitleTextAttributes(seg.Handle, nsDic, state) #else #Pragma Unused seg #Pragma Unused c #Pragma Unused state #EndIf End Sub
End Module
Module TableExtensionsXC
Enum selectionStyle none = 0 blue grey default End Enum
Enum separatorStyle none = 0 singleLine End Enum
Sub AdjustsFontSizeToFitWidthDetailXC(extends cell As MobileTableCellData, lines As Integer = -1) Dim label As Ptr declare function getTextLabel lib "UIKit.framework" selector "detailTextLabel" (obj_ref as ptr) as ptr label = getTextLabel(cell.Handle) If lines > 0 Then Declare Sub setNumberOfLines Lib "UIKit.framework" selector "setNumberOfLines:" (id As ptr, value As Integer) setNumberOfLines label, lines End If Declare sub setAdjustsFontSizeToFitWidth lib "UIKit.framework" selector "setAdjustsFontSizeToFitWidth:" (id as ptr, value as Boolean) setAdjustsFontSizeToFitWidth label, True End Sub
Sub AdjustsFontSizeToFitWidthXC(extends cell As MobileTableCellData, lines As Integer = -1) Dim label As Ptr declare function getTextLabel lib "UIKit.framework" selector "textLabel" (obj_ref as ptr) as ptr label = getTextLabel(cell.Handle) If lines > 0 Then Declare Sub setNumberOfLines Lib "UIKit.framework" selector "setNumberOfLines:" (id As ptr, value As Integer) setNumberOfLines label, lines End If Declare sub setAdjustsFontSizeToFitWidth lib "UIKit.framework" selector "setAdjustsFontSizeToFitWidth:" (id as ptr, value as Boolean) setAdjustsFontSizeToFitWidth label, True End Sub
Sub DetailTextColorXC(extends cell As MobileTableCellData, assigns value As Color) cell.SetDetailTextColorXC(value) End Sub
Sub FlashScrollIndicatorsXC(extends table As iOSMobileTable) Declare Sub flashScrollIndicators_ Lib "UIKit.framework" selector "flashScrollIndicators" (obj_id As ptr) flashScrollIndicators_(table.Handle) End Sub
Function GetHeaderViewXC(extends table As iOSMobileTable) As ptr declare function tableHeaderView lib "UIKit.framework" selector "tableHeaderView" (obj_id as ptr) as ptr return tableHeaderView(table.Handle) End Function
Function GetScrollPositionXC(extends table As iOSMobileTable) As Integer() Declare Function indexPathsForVisibleRows Lib "UIKit.framework" selector "indexPathsForVisibleRows" (obj_id As ptr) As ptr Dim indexArray As ptr = indexPathsForVisibleRows(table.Handle) If indexArray <> Nil Then Declare Function objectAtIndex Lib "Foundation.framework" selector "objectAtIndex:" (theArray As Ptr, idx As Integer) As Ptr Declare Function getRow Lib "Foundation.framework" selector "row" (obj_id As ptr) As Integer Declare Function getSection Lib "Foundation.framework" selector "section" (obj_id As ptr) As Integer Dim indexPath As Ptr = objectAtIndex(indexArray, 0) Dim section, row As Integer section = getSection(indexPath) row = getRow(indexPath) Return Array(section, row) End If Return Array(-1, -1) End Function
Function SectionRowAtPointXC(extends t As iOSMobileTable, location As point) As Integer() #if ExtensionsXC.kUseUIKit Declare function indexPathForRowAtPoint lib UIKitLib selector "indexPathForRowAtPoint:" (obj as ptr, pt as ExtensionsXC.xcCGPoint) as ptr Dim pt As ExtensionsXC.xcCGPoint pt.x = location.X pt.y = location.Y Dim indexPath As new Foundation.NSIndexPath( indexPathForRowAtPoint(t.Handle, pt) ) Dim sectionrow() As Integer if indexPath.isNil then return nil Else sectionrow.Append indexPath.section sectionrow.Append indexPath.row return sectionrow end if #else Break #Pragma Unused t #Pragma Unused location #endif End Function
Sub SelectRowXC(extends table as iOSMobileTable, section as integer, row as integer, animated as Boolean = True, scrollPosition as iOSMobileTable.ScrollPositions = iOSMobileTable.ScrollPositions.None) //new v2.3 declare sub selectRowAtIndexPath lib "UIKit" selector "selectRowAtIndexPath:animated:scrollPosition:" (id as Ptr, row as Ptr, animated as boolean, scrollPosition as integer) Declare Function NSClassFromString Lib "Foundation" (className As CFStringRef) As Ptr Declare Function init Lib "UIKit" selector "indexPathForRow:inSection:" (id As ptr, row As Integer, section As Integer) as ptr Dim idxPath As ptr = init(NSClassFromString("NSIndexPath"), row, section) selectRowAtIndexPath(table.Handle, idxPath, animated, Integer(scrollPosition)) End Sub
Sub SetAllowsSelectionDuringEditingXC(extends table As iOSMobileTable, value As Boolean) Declare Sub setallowsSelectionDuringEditing Lib "UIKit" Selector "setAllowsSelectionDuringEditing:" (id As Ptr, value As Boolean) setallowsSelectionDuringEditing(table.Handle, value) End Sub
Sub SetAllowsSelectionXC(extends table As iOSMobileTable, value As Boolean) Declare Sub setallowsSelection Lib "UIKit.framework" Selector "setAllowsSelection:" (id as ptr, value as Boolean) setallowsSelection(table.Handle, value) End Sub
Sub SetBackgroundColorXC(extends cell as MobileTableCellData, value as Color) Dim uic As UIKit.UIColor If value.Alpha = 255 Then uic = UIKit.UIColor.ClearColor Else uic = New UIColor(value) End If Declare Sub setBackgroundColor_ Lib "UIKit.framework" selector "setBackgroundColor:" (obj_id As ptr, col As ptr) setBackgroundColor_(cell.handle, uic) End Sub
Sub SetBackgroundColorXC(extends action As iOSMobileTableRowAction, value as Color) Dim uic As UIKit.UIColor If value.Alpha = 255 Then uic = UIKit.UIColor.ClearColor Else uic = New UIColor(value) End If declare sub setBackgroundColor lib "UIKit.framework" selector "setBackgroundColor:" (obj_id as ptr, col as ptr) setBackgroundColor(action.handle, uic) End Sub
Sub SetBackgroundViewColorXC(extends cell as MobileTableCellData, value as Color) Dim uic As UIKit.UIColor If value.Alpha = 255 Then uic = UIKit.UIColor.ClearColor Else uic = New UIColor(value) End If Declare function backgroundView lib "UIkit.framework" selector "backgroundView" (obj as ptr) as ptr dim back As ptr = BackgroundView(cell.Handle) Declare Sub setBackgroundColor_ Lib "UIKit.framework" selector "setBackgroundColor:" (obj_id As ptr, col As ptr) setBackgroundColor_(back, uic) End Sub
Sub SetBouncesXC(extends table As iOSMobileTable, value As Boolean) declare sub bounces_ lib "UIKit.framework" selector "setBounces:" (obj_id as ptr, value as Boolean) bounces_(table.handle, value) End Sub
Sub SetDetailTextColorXC(extends cell As MobileTableCellData, value As Color) Dim label As Ptr Dim uic As UIKit.UIColor If value.Alpha = 255 Then uic = UIKit.UIColor.ClearColor Else uic = New UIColor(value) end if declare function getTextLabel lib "UIKit.framework" selector "detailTextLabel" (obj_ref as ptr) as ptr label = getTextLabel(cell.Handle) declare sub setTextColor lib "UIKit.framework" selector "setTextColor:" (obj_id as ptr, col as ptr) setTextColor(label, uic) End Sub
Sub SetFontsXC(extends cell As MobileTableCellData, textFont As Font, detailFont As Font = nil) // TODO chanage to Font class Declare Function NSClassFromString Lib "Foundation" (className As CFStringRef) As Ptr Declare Function initFont Lib "UIKit.framework" selector "fontWithName:size:" (obj_id As ptr, name As CFStringRef, size As CGFloat) As ptr Dim fontPtr As ptr Dim sz As Double = textFont.Size fontPtr = initFont(NSClassFromString("UIFont"), textFont.Name, sz) Declare Function getTextLabel Lib "UIKit.framework" selector "textLabel" (obj_ref As ptr) As ptr Declare Function getDetailTextLabel Lib "UIKit.framework" selector "detailTextLabel" (obj_ref As ptr) As ptr Declare sub setFont lib "UIKit.framework" selector "setFont:" (obj_ref as ptr, fontRef as ptr) Dim label As Ptr label = getTextLabel(cell.Handle) setFont(label, fontPtr) Dim detailLabel As Ptr detailLabel = getDetailTextLabel(cell.Handle) If detailFont is nil then setFont(detailLabel, fontPtr) Else Dim detailfontPtr As ptr detailFontPtr = initFont(NSClassFromString("UIFont"), detailFont.Name, detailFont.Size) setFont(detailLabel, detailfontPtr) End If End Sub
Sub SetFontsXC(extends cell As MobileTableCellData, textFontName As String, textFontSize As Double, detailFontName As String = "", detailFontSize As Double = 0.0) // TODO chanage to Font class Declare Function NSClassFromString Lib "Foundation" (className As CFStringRef) As Ptr Declare Function initFont Lib "UIKit.framework" selector "fontWithName:size:" (obj_id As ptr, name As CFStringRef, size As CGFloat) As ptr Dim fontPtr As ptr fontPtr = initFont(NSClassFromString("UIFont"), textFontName, textFontSize) Declare Function getTextLabel Lib "UIKit.framework" selector "textLabel" (obj_ref As ptr) As ptr Declare Function getDetailTextLabel Lib "UIKit.framework" selector "detailTextLabel" (obj_ref As ptr) As ptr Declare sub setFont lib "UIKit.framework" selector "setFont:" (obj_ref as ptr, fontRef as ptr) Dim label As Ptr label = getTextLabel(cell.Handle) setFont(label, fontPtr) Dim detailLabel As Ptr detailLabel = getDetailTextLabel(cell.Handle) If detailFontName.isEmpty Then setFont(detailLabel, fontPtr) Else Dim detailfontPtr As ptr detailFontPtr = initFont(NSClassFromString("UIFont"), detailFontName, detailFontSize) setFont(detailLabel, detailfontPtr) End If End Sub
Sub SetFooterViewXC(extends table As iOSMobileTable, footerView As ptr) declare sub tableFooterView lib "UIKit.framework" selector "setTableFooterView:" (obj_id as ptr, headerv as ptr) tableFooterView(table.Handle, footerView) End Sub
Sub SetHeaderViewXC(extends table As iOSMobileTable, headerView As ptr) declare sub tableHeaderView lib "UIKit.framework" selector "setTableHeaderView:" (obj_id as ptr, headerv as ptr) tableHeaderView(table.Handle, headerView) End Sub
Sub SetHideRemainingSeparatorsXC(extends table As iOSMobileTable) Declare Function initWithFrame Lib "Foundation.framework" selector "initWithFrame:" (obj_id As ptr, frame As ExtensionsXC.xcCGRect) As ptr dim frame as ExtensionsXC.xcCGRect frame.origin.x = 0 frame.origin.y = 0 frame.rsize.height = 0 frame.rsize.width = 0 Declare Function alloc Lib "Foundation.framework" selector "alloc" (clsRef As ptr) As ptr Declare Function NSClassFromString Lib "Foundation.framework" (clsName As CFStringRef) As ptr Dim view As ptr = initwithFrame(alloc(NSClassFromString("UIView")), frame) table.SetFooterViewXC(view) End Sub
Sub SetIconXC(extends action As iOSMobileTableRowAction, icon As Picture, backColor As Color, width As Integer = 70, height As Integer = 44) #if DebugBuild Break //This function does not work anymore If icon Is Nil Then Return Dim scale As Double = ExtensionsXC.MainScreenScaleXC //Creating a bitmap that will hold the icon Dim bitmap As new Picture(width*scale, height*scale) bitmap.HorizontalResolution = 72*scale bitmap.VerticalResolution = 72*scale Dim g As Graphics = bitmap.Graphics g.Scale(scale, scale) g.DrawingColor = backColor g.FillRectangle(0, 0, g.Width, g.Height) g.DrawPicture(icon, (g.Width-icon.Width)/2, (g.Height-icon.Height)/2) 'Dim img As New iOSBitmap(width, height, scale) 'Dim g As iOSGraphics = img.Graphics 'g.Scale(scale, scale) ' 'g.FillColor = backColor 'g.FillRect(0, 0, g.Width, g.Height) ' 'g.DrawImage(icon, (g.Width-icon.Width)/2, (g.Height-icon.Height)/2) Declare Function objc_getClass Lib "/usr/lib/libobjc.dylib" (aClassName As CString) As Ptr Dim theUIColorClassRef As Ptr = objc_getClass("UIColor") //Creating a UIColor using the bitmap as a pattern Declare Function decl_GetColorWithRGBA Lib "UIKit" selector "colorWithPatternImage:" (UIColorClassRef As Ptr, imgRef As Ptr) As Ptr Dim uic As ptr = decl_GetColorWithRGBA(theUIColorClassRef, bitmap.CopyOSHandle(Picture.HandleType.iOSUIImage)) Declare Sub setBackgroundColor Lib "UIKit.framework" selector "setBackgroundColor:" (obj_id As ptr, col As ptr) SetBackgroundColor(action.handle, uic) #endif End Sub
Sub SetIndicatorStyleXC(extends table as iOSMobileTable, value as ScrollViewExtensionsXC.UIScrollViewIndicatorStyle) Declare Sub setIndicatorStyle_ Lib "UIKit.framework" selector "setIndicatorStyle:" (obj_id As ptr, value As ScrollViewExtensionsXC.UIScrollViewIndicatorStyle) setIndicatorStyle_(table.Handle, value) End Sub
Sub SetScrollEnabledXC(extends table as iOSMobileTable, value As Boolean) Declare Sub scrollEnabled Lib "UIKit.framework" selector "setScrollEnabled:" (obj_id As ptr, value As Boolean) scrollenabled(table.Handle, value) End Sub
Sub SetScrollbarVisibleXC(extends table as iOSMobileTable, value as Boolean) //Hide scrollbar Declare Sub setScrollIndicator lib "UIKit.framework" selector "setShowsVerticalScrollIndicator:" (id as ptr, value as Boolean) setScrollIndicator table.Handle, value End Sub
Sub SetScrollsToTopXC(extends table as iOSMobileTable, value As Boolean) Declare Sub scrollsToTop_ Lib "UIKit.framework" selector "setScrollsToTop:" (obj_id As ptr, value As Boolean) scrollsToTop_(table.Handle, value) End Sub
Sub SetSectionHeaderTopPaddingXC(extends table As iOSMobileTable, value As Double) if ExtensionsXC.GetiOSVersionXC >= 15.0 Then Declare sub sectionHeaderTopPadding lib "UIKit" Selector "setSectionHeaderTopPadding:" (obj as ptr, value as CGFloat) sectionHeaderTopPadding(table.Handle, value) end if End Sub
Sub SetSelectedBackgroundColorXC(extends cell as MobileTableCellData, value as Color) 'UIView *bgColorView = [[UIView alloc] init]; 'bgColorView.backgroundColor = [UIColor redColor]; '[cell setSelectedBackgroundView:bgColorView]; Declare Function init Lib "Foundation.framework" selector "init" (obj_id As ptr) As ptr Declare Function alloc Lib "Foundation.framework" selector "alloc" (clsRef As ptr) As ptr Declare Function NSClassFromString Lib "Foundation.framework" (clsName As CFStringRef) As ptr Declare Sub setBackgroundColor_ Lib "UIKit.framework" selector "setBackgroundColor:" (obj_id As ptr, col As ptr) Dim bgColorView As ptr = init(alloc(NSClassFromString("UIView"))) Dim uic As UIColor If value.Alpha = 255 Then uic = UIColor.ClearColor Else uic = New UIColor(value) End If setBackgroundColor_(bgColorView, uic) Declare Sub setSelectedBackgroundView_ Lib "UIKit.framework" selector "setSelectedBackgroundView:" (obj_id As ptr, view As ptr) setSelectedBackgroundView_(cell.Handle, bgColorView) End Sub
Sub SetSelectedDetailTextColorXC(extends cell as MobileTableCellData, value as Color) Dim label As Ptr Declare Function getTextLabel Lib "UIKit.framework" selector "detailTextLabel" (obj_ref As ptr) As ptr label = getTextLabel(cell.Handle) Dim uic As UIColor If value.Alpha = 255 Then uic = UIColor.ClearColor Else uic = New UIColor(value) End If Declare Sub setHighlightedTextColor_ Lib "UIKit.framework" selector "setHighlightedTextColor:" (obj_id As ptr, col As ptr) setHighlightedTextColor_(label, uic) End Sub
Sub SetSelectedTextColorXC(extends cell as MobileTableCellData, value as Color) Dim label As Ptr Declare Function getTextLabel Lib "UIKit.framework" selector "textLabel" (obj_ref As ptr) As ptr label = getTextLabel(cell.Handle) Dim uic As UIColor If value.Alpha = 255 Then uic = UIColor.ClearColor Else uic = New UIColor(value) End If Declare Sub setHighlightedTextColor_ Lib "UIKit.framework" selector "setHighlightedTextColor:" (obj_id As ptr, col As ptr) setHighlightedTextColor_(label, uic) End Sub
Sub SetSelectionStyleXC(extends cell As MobileTableCellData, style As TableExtensionsXC.selectionStyle) Declare Sub setselectionStyle_ Lib "UIKit.framework" selector "setSelectionStyle:" (obj_id As ptr, style As selectionStyle) setselectionStyle_(cell.Handle, style) End Sub
Sub SetSeparatorColorXC(extends table As iOSMobileTable, value As Color) Dim uic As UIKit.UIColor If value.Alpha = 255 Then uic = UIKit.UIColor.ClearColor Else uic = New UIColor(value) End If Declare Sub setSeparatorColor Lib "UIKit.framework" selector "setSeparatorColor:" (id As ptr, UIColor As Ptr) setSeparatorColor table.Handle, uic End Sub
Sub SetSeparatorStyleXC(extends table As iOSMobileTable, value As TableExtensionsXC.separatorStyle) Declare Sub setSeparatorStyle Lib "UIKit.framework" selector "setSeparatorStyle:"(o As ptr, mode As separatorStyle) setSeparatorStyle(table.handle, value) End Sub
Sub SetTableCellBreakXC(extends cell As MobileTableCellData, BreakValue As ControlExtensionsXC.NSLineBreakMode) Dim label As Ptr declare function getTextLabel lib "UIKit.framework" selector "textLabel" (obj_ref as ptr) as ptr label = getTextLabel(cell.Handle) Declare sub setLineBreakMode lib "UIKit.framework" selector "setLineBreakMode:" (id as ptr, value as ControlExtensionsXC.NSLineBreakMode) setLineBreakMode label, BreakValue Declare sub setNumberOfLines lib "UIKit.framework" selector "setNumberOfLines:" (id as ptr, value as integer) setNumberOfLines label, 3 cell.AdjustsFontSizeToFitWidthXC() End Sub
Sub SetTableCellDetailBreakXC(extends cell As MobileTableCellData, BreakValue As ControlExtensionsXC.NSLineBreakMode, lines As Integer = 3) Dim label As Ptr declare function getTextLabel lib "UIKit.framework" selector "detailTextLabel" (obj_ref as ptr) as ptr label = getTextLabel(cell.Handle) Declare Sub setLineBreakMode Lib "UIKit.framework" selector "setLineBreakMode:" (id As ptr, value As ControlExtensionsXC.NSLineBreakMode) setLineBreakMode label, BreakValue Declare sub setNumberOfLines lib "UIKit.framework" selector "setNumberOfLines:" (id as ptr, value as integer) setNumberOfLines label, lines cell.AdjustsFontSizeToFitWidthXC() End Sub
Sub SetTextAlignmentXC(extends cell As MobileTableCellData, alignment As ControlExtensionsXC.NSTextAlignment) //New in version 2.0 Dim label As Ptr Declare Function getTextLabel Lib "UIKit.framework" selector "textLabel" (obj_ref As ptr) As ptr label = getTextLabel(cell.Handle) Declare Sub setTextAlignment Lib "UIKit.framework" selector "setTextAlignment:" (id As ptr, value As ControlExtensionsXC.NSTextAlignment) setTextAlignment(label, alignment) End Sub
Sub SetTextColorXC(extends cell As MobileTableCellData, value As Color) Dim label As Ptr Dim uic As UIKit.UIColor If value.Alpha = 255 Then uic = UIKit.UIColor.ClearColor Else uic = New UIColor(value) End If Declare Function getTextLabel Lib "UIKit.framework" selector "textLabel" (obj_ref As ptr) As ptr label = getTextLabel(cell.Handle) Declare Sub setTextColor_ Lib "UIKit.framework" selector "setTextColor:" (obj_id As ptr, col As ptr) setTextColor_(label, uic) End Sub
Sub TextColorXC(extends cell As MobileTableCellData, assigns value As Color) cell.SetTextColorXC(value) End Sub
Sub UnselectTableRowXC(extends table As iOSMobileTable) declare sub selectRow lib "UIKit.framework" selector "selectRowAtIndexPath:animated:scrollPosition:" (id as Ptr, row as Ptr, animated as boolean, scrollPosition as integer) selectRow(table.Handle, nil, false, 0) End Sub
End Module
Module TextFieldExtensionsXC
Enum UIKeyboardAppearance default = 0 dark light End Enum
Enum UIKeyboardType default = 0 asciiCapable numbersAndPunctuation URL numberPad phonePad namePhonePad emailAddress decimalPad twitter webSearch asciiCapableNumberPad End Enum
Enum UIReturnKeyType Default Go Google Join Next_ Route Search Send Yahoo Done EmergencyCall Continue_ End Enum
Enum UITextAutocapitalizationType None = 0 Words Sentences AllCharacters End Enum
Enum UITextAutocorrectionType Default = 0 No Yes End Enum
Enum UITextFieldBorderStyle None = 0 Line Bezel RoundedRect End Enum
Enum UITextFieldViewMode never whileEditing unlessEditing always End Enum
Sub AddDoneToolbarButtonXC(extends area As MobileTextArea, Translucent As Boolean = True) AddDoneToolbarButtonXC_internal(area, Translucent) End Sub
Sub AddDoneToolbarButtonXC(extends field As MobileTextField, Translucent As Boolean = True) AddDoneToolbarButtonXC_internal(field, Translucent) End Sub
Private Sub AddDoneToolbarButtonXC_internal(txt As MobileTextControl, Translucent As Boolean) Declare Function NSClassFromString Lib "Foundation" (name As CFStringRef) As Ptr Declare Function alloc Lib "Foundation" selector "alloc" (clsRef As ptr) As ptr declare function init lib "Foundation" selector "init" (obj_id as ptr) as ptr Declare sub setInputAccessoryView lib "UIKit" selector "setInputAccessoryView:" (obj as ptr, value as ptr) Declare sub sizeToFit lib "UIKit" selector "sizeToFit" (obj as ptr) //Creating Toolbuttons Dim flexItem as MobileToolbarButton = new MobileToolbarButton(MobileToolbarButton.Types.FlexibleSpace) Dim doneItem As MobileToolbarButton = new MobileToolbarButton(MobileToolbarButton.types.Done) 'doneItem.Tag = "close" Declare sub setTarget lib "UIKit" selector "setTarget:" (obj as ptr, value as ptr) Declare Function view lib "Foundation" selector "view" (classRef as Ptr) as Ptr 'setTarget(doneItem.Handle, self.ViewControllerHandle) Declare sub setAction lib "UIKit" Selector "setAction:" (obj as ptr, sel as ptr) declare function NSSelectorFromString lib "Foundation" (aSelectorName as CFStringRef) as Ptr setAction(doneItem.Handle, NSSelectorFromString("barButtonPressed:")) //xojo makes it complex creating a new toolbar Dim toolbar_ptr As ptr = init(alloc(NSClassFromString("UIToolbar"))) sizeToFit(toolbar_ptr) //Keeping a reference to the toolbar 'self.toolbarPtr = toolbar declare sub translucent_ lib UIKitLib selector "setTranslucent:" (obj_id as ptr, translucent as Boolean) translucent_(toolbar_ptr, Translucent) Declare Function arrayWithCapacity Lib "Foundation" selector "arrayWithCapacity:" (cls As ptr, count as UInteger) As ptr Declare Sub addObject Lib "Foundation" selector "addObject:" (arr As ptr, obj As ptr) //Creating an array of toolbuttons Dim nsArray_ptr As ptr = arrayWithCapacity(NSClassFromString("NSMutableArray"), 2) addObject(nsArray_ptr, flexItem.Handle) addObject(nsArray_ptr, doneItem.Handle) //Adding the items to the toolbar Declare sub setItems lib "UIKit" selector "setItems:animated:" (obj as ptr, items as ptr, animated as Boolean) setItems(toolbar_ptr, nsArray_ptr, false) //Attaching the toolbar to the textfield setInputAccessoryView(txt.Handle, toolbar_ptr) End Sub
Protected Function CGRectMake(x As CGFloat, y As CGFloat, width As CGFloat, height As CGFloat) As ExtensionsXC.xcCGRect Dim origin As ExtensionsXC.xcCGPoint origin.x = x origin.y = y Dim size As ExtensionsXC.xcCGSize size.width = width size.height = height Dim rect As ExtensionsXC.xcCGRect rect.origin = origin rect.rsize = size Return rect End Function
Function GetScrollPositionXC(extends area As MobileTextArea) As Point Dim offset As point Declare Function ContentOffset_ Lib "UIKit.framework" selector "contentOffset" (obj_id As ptr) As ExtensionsXC.xcCGPoint Dim pt As ExtensionsXC.xcCGPoint = ContentOffset_(area.Handle) offset = New Point(pt.x, pt.y) Return offset End Function
Function GetSelectedRangeXC(Extends area As MobileTextArea) As TextFieldExtensionsXC.NSRangeXC Declare Function selectedRange_ Lib "UIKit.framework" selector "selectedRange" (obj_id As ptr) As NSRangeXC Return selectedRange_(area.Handle) End Function
Sub ScrollToRangeXC(Extends area As MobileTextArea, range As TextFieldExtensionsXC.NSRangeXC) Declare Sub scrollRangeToVisible_ Lib "UIKit.framework" selector "scrollRangeToVisible:" (obj_id As ptr, rng As NSRangeXC) scrollRangeToVisible_(area.Handle, range) End Sub
Sub ScrollToXC(extends area As MobileTextArea, point As Point, animated As Boolean = True) Declare Sub setContentOffsetAnimated Lib "UIKit.framework" selector "setContentOffset:animated:" (id As ptr, value As ExtensionsXC.xcCGPoint, animated As Boolean) Dim pt As ExtensionsXC.xcCGPoint pt.x = point.X pt.y = point.Y setContentOffsetAnimated(area.Handle, pt, animated) End Sub
Sub SetAutocapitalizationTypeXC(extends field As MobileTextField, value As TextFieldExtensionsXC.UITextAutocapitalizationType) Declare Sub setAutocapitalizationType_ Lib "UIKit.framework" selector "setAutocapitalizationType:" (obj_id As ptr, value As UITextAutoCapitalizationType) setAutocapitalizationType_(field.Handle, value) End Sub
Sub SetAutocorrectionTypeXC(extends area As MobileTextArea, value As TextFieldExtensionsXC.UITextAutocorrectionType) Declare Sub setAutocorrectionType_ Lib "UIKit.framework" selector "setAutocorrectionType:" (obj_id As ptr, value As UITextAutocorrectionType) setAutocorrectionType_(area.Handle, value) End Sub
Sub SetAutocorrectionTypeXC(extends field As MobileTextField, value As TextFieldExtensionsXC.UITextAutocorrectionType) Declare Sub setAutocorrectionType_ Lib "UIKit.framework" selector "setAutocorrectionType:" (obj_id As ptr, value As UITextAutocorrectionType) setAutocorrectionType_(field.Handle, value) End Sub
Sub SetBorderStyleXC(extends field As MobileTextField, style As TextFieldExtensionsXC.UITextFieldBorderStyle) declare sub setBorderStyle lib "UIKit.framework" selector "setBorderStyle:" (obj_id as ptr, st as UITextFieldBorderStyle) setBorderStyle(field.handle, style) End Sub
Sub SetBorderWidthXC(extends field As MobileTextField, value As Double) Declare Function layer_ Lib "UIKit.framework" selector "layer" (id As ptr) As Ptr Dim layer As ptr = layer_(field.Handle) Declare Sub setBorderWidth Lib "UIKit.framework" selector "setBorderWidth:" (obj_id As ptr, w As CGFloat) setBorderWidth(layer, value) End Sub
Sub SetKeyboardAppearanceXC(extends field As MobileTextField, appearance As TextFieldExtensionsXC.UIKeyboardAppearance) Declare Sub setKeyboardAppearance Lib "UIKit.framework" selector "setKeyboardAppearance:" (id As ptr, value As UIKeyboardAppearance) setKeyboardAppearance field.Handle, appearance End Sub
Sub SetKeyboardTypeXC(extends field As MobileTextField, type As TextFieldExtensionsXC.UIKeyboardType) Declare Sub setKeyboardType Lib "UIKit.framework" selector "setKeyboardType:" (id As ptr, value As UIKeyboardType) setKeyboardType field.Handle, type End Sub
Sub SetLeftViewIconXC(extends field As MobileTextField, image As Picture, addIndent As Double = 0.0) dim spacerView As new MobileImageViewer spacerView.Image = image Declare Function frame_ Lib "UIKit.framework" selector "frame" (obj_id As ptr) As ExtensionsXC.xcCGRect Declare sub setFrame_ lib "UIKit.framework" selector "setFrame:" (obj_id as ptr, frame as ExtensionsXC.xcCGRect) 'Dim rect As new Foundation.NSRect(0, 0, indent, 10) 'spacerView = new UIKit.UIView(rect) declare sub setLeftViewMode lib "UIKit.framework" selector "setLeftViewMode:" (id as ptr, value as UITextFieldViewMode) setLeftViewMode field.Handle, UITextFieldViewMode.always declare sub setLeftView lib "UIKit.framework" selector "setLeftView:" (id as ptr, view as ptr) setLeftView field.Handle, spacerView.Handle Dim frame As ExtensionsXC.xcCGRect = frame_(spacerView.handle) frame.rsize.width = image.Width + addIndent frame.rsize.height = image.Height setFrame_(spacerView.handle, frame) End Sub
Sub SetPlaceholderColorXC(extends field As MobileTextField, placeholder As String, aColor As Color) if placeholder.trim.isEmpty then Return #If ExtensionsXC.kUseUIKit 'NSAttributedString *str = [[NSAttributedString alloc] initWithString:@"Some Text" attributes:@{ NSForegroundColorAttributeName : [UIColor redColor] }]; Declare Function alloc Lib "Foundation" selector "alloc" (clsRef As ptr) As ptr Declare Function NSClassFromString Lib "Foundation" (clsName As CFStringRef) As ptr Declare Function initWithStringattributes Lib "Foundation" selector "initWithString:attributes:" (id As ptr, astring As CFStringRef, attDict As ptr) As ptr Declare Sub attributedPlaceholder_ Lib "Foundation" selector "setAttributedPlaceholder:" (id As ptr, attribString As ptr) Dim uic As New UIColor(aColor) Dim keyStr As New NSString(Foundation.StringConstant("UIKit", "NSForegroundColorAttributeName")) 'Dim keyStr2 As new NSString(Foundation.StringConstant("UIKit", "NSBackgroundColorAttributeName")) Dim keys() As Foundation.NSObject Dim vals() As Foundation.NSObject keys.Append keyStr vals.Append uic 'keys.Append keyStr2 'vals.Append UIColor.Red Dim attrib As New Foundation.NSMutableDictionary(keys, vals) Dim attribString As ptr = initWithStringattributes(alloc(NSClassFromString("NSAttributedString")), placeholder, attrib) attributedPlaceholder_(field.Handle, attribString) #else #Pragma Unused field #Pragma Unused placeholder #Pragma Unused aColor #EndIf End Sub
Sub SetReturnKeyTypeXC(extends field as MobileTextField, value as TextFieldExtensionsXC.UIReturnKeyType) Declare Sub setReturnKeyType_ Lib "UIKit.framework" selector "setReturnKeyType:" (obj_id As ptr, value As UIReturnKeyType) setReturnKeyType_(field.Handle, value) End Sub
Sub SetScrollsToTopXC(extends area As MobileTextArea, value As Boolean) Declare Sub scrollsToTop_ Lib "UIKit.framework" selector "setScrollsToTop:" (obj_id As ptr, value As Boolean) scrollsToTop_(area.Handle, value) End Sub
Sub SetSelectedRangeXC(Extends area As MobileTextArea, range As TextFieldExtensionsXC.NSRangeXC) Declare Sub selectedRange Lib "UIKit.framework" selector "setSelectedRange:" (obj_id As ptr, rng As NSRangeXC) Declare Sub select_ Lib "UIKit.framework" selector "select:" (obj_id As ptr, obj As ptr) select_(area.Handle, area.Handle) selectedRange(area.Handle, range) End Sub
Sub SetTabOrder(extends field As MobileTextField, value As Integer) declare sub setTag lib "UIKit.framework" selector "setTag:" (obj_id as ptr, value as Integer) SetTag(field.Handle, value) End Sub
Sub SetTextIndentXC(extends field as MobileTextField, indent As Integer) Declare Function alloc Lib "Foundation.framework" selector "alloc" (clsRef As ptr) As ptr Declare Function NSClassFromString Lib "Foundation.framework" (clsName As CFStringRef) As ptr Declare Function initWithFrame Lib "Foundation.framework" selector "initWithFrame:" (obj_id As ptr, frame As ExtensionsXC.xcCGRect) As ptr Dim frame As ExtensionsXC.xcCGRect frame.origin.x = 0 frame.origin.y = 0 frame.rsize.width = indent frame.rsize.height = 10 Dim spacerView As ptr = initwithFrame(alloc(NSClassFromString("UIView")), frame) 'Dim spacerView As UIKit.UIView 'Dim rect As New Foundation.NSRect(0, 0, indent, 10) 'spacerView = new UIKit.UIView(rect) declare sub setLeftViewMode lib "UIKit.framework" selector "setLeftViewMode:" (id as ptr, value as UITextFieldViewMode) setLeftViewMode field.Handle, UITextFieldViewMode.always declare sub setLeftView lib "UIKit.framework" selector "setLeftView:" (id as ptr, view as ptr) setLeftView field.Handle, spacerView End Sub
Sub x_SetBorderColorXC(extends field As MobileTextField, C As Color) Declare Function layer_ Lib "UIKit.framework" selector "layer" (id As ptr) As Ptr Dim layer As ptr = layer_(field.Handle) Dim uic As UIKit.UIColor if c.Alpha = 255 then uic = UIKit.UIColor.ClearColor else uic = new UIKit.UIColor(c) end if declare sub setBorderColor lib "UIKit.framework" selector "setBorderColor:" (obj_id as ptr, col as ptr) setBorderColor(layer, uic.CGColor) End Sub
Note "About"
For better organization of code, this module has MobileTextField and MobileTextArea extensions.
Structure NSRangeXC loc As Uinteger len As UInteger End Structure
End Module
Module ViewExtensionsXC
Enum LargeTitleDisplayMode automatic = 0 always never End Enum
Enum UIModalPresentationStyle fullscreen = 0 pageSheet formSheet currentContext custom overFullScreen overCurrentContext popover none = -1 automatic = -2 End Enum
Enum UIModalTransitionStyle coverVertical = 0 flipHorizontal crossDissolve partialCurl End Enum
Enum UIRectCorners all = 0 TopLeft = 1 TopRight = 2 BottomLeft = 4 BottomRight = 8 End Enum
Enum UISheetPresentationControllerDetent medium large medium_large End Enum
Enum UISplitViewControllerDisplayMode Automatic = 0 secondaryOnly oneBesideSecondary oneOverSecondary End Enum
Enum UIUserInterfaceLayoutDirection leftToRight rightToLeft End Enum
Enum UIViewAnimationOptions UIViewAnimationOptionRepeat = 8 UIViewAnimationOptionTransitionCrossDissolve = 5242880 UIViewAnimationOptionAutoreverse = 16 UIViewAnimationOptionTransitionFlipFromTop = 6291456 UIViewAnimationOptionTransitionFlipFromBottom = 7340032 UIViewAnimationOptionTransitionNone = 0 End Enum
Sub AddProgressXC(extends mView As MobileContainer, ByRef Progress As MobileProgressWheel, DarkBackground As Boolean = False) Progress = new MobileProgressWheel If DarkBackground Then Progress.SetActivityIndicatorViewStyleXC(ControlExtensionsXC.UIActivityIndicatorViewStyle.whiteLarge) Else Progress.SetActivityIndicatorViewStyleXC(ControlExtensionsXC.UIActivityIndicatorViewStyle.whiteLarge) declare sub setColor lib "UIKit.framework" selector "setColor:" (obj_id as ptr, col as ptr) setColor(Progress.handle, UIColor.Gray) end if mView.AddControl(Progress) Dim cons As new iOSLayoutConstraint(Progress, _ iOSLayoutConstraint.AttributeTypes.CenterX, _ iOSLayoutConstraint.RelationTypes.Equal, _ mView, _ iOSLayoutConstraint.AttributeTypes.CenterX, _ 1, _ 0) cons.Active = True mView.AddConstraint(cons) cons = new iOSLayoutConstraint(Progress, _ iOSLayoutConstraint.AttributeTypes.CenterY, _ iOSLayoutConstraint.RelationTypes.Equal, _ mView, _ iOSLayoutConstraint.AttributeTypes.CenterY, _ 1, _ 0) cons.Active = True mView.AddConstraint(cons) End Sub
Sub AddProgressXC(extends mView As MobileScreen, ByRef Progress As MobileProgressWheel, DarkBackground As Boolean = False) Progress = New MobileProgressWheel Progress.SetActivityIndicatorViewStyleXC(ControlExtensionsXC.UIActivityIndicatorViewStyle.whiteLarge) If Not DarkBackground Then Declare Sub setColor Lib "UIKit.framework" selector "setColor:" (obj_id As ptr, col As ptr) setColor(Progress.handle, UIColor.Gray) End If mView.AddControl(Progress) Dim cons As New iOSLayoutConstraint(Progress, _ iOSLayoutConstraint.AttributeTypes.CenterX, _ iOSLayoutConstraint.RelationTypes.Equal, _ mView, _ iOSLayoutConstraint.AttributeTypes.CenterX, _ 1, _ 0) cons.Active = True mView.AddConstraint(cons) cons = New iOSLayoutConstraint(Progress, _ iOSLayoutConstraint.AttributeTypes.CenterY, _ iOSLayoutConstraint.RelationTypes.Equal, _ mView, _ iOSLayoutConstraint.AttributeTypes.CenterY, _ 1, _ 0) cons.Active = True mView.AddConstraint(cons) End Sub
Protected Sub AnimateWithDurationXC(duration as Double, animationBlock as iOSBlock, completion as iOSBlock = nil) https://developer.apple.com/documentation/uikit/uiview/1622515-animatewithduration?language=objc Dim classPtr As ptr Declare sub animateWithDuration_ lib UIKitLib selector "animateWithDuration:animations:completion:" _ (id as ptr, duration as Double, animations as ptr, completion as ptr) declare function NSClassFromString lib "Foundation" (clsName as cfstringref) as ptr classPtr = NSClassFromString("UIView") if completion is nil then animateWithDuration_ classptr, duration, animationBlock.handle, nil else animateWithDuration_ classptr, duration, animationBlock.handle, completion.Handle end if End Sub
Sub DismissViewControllerXC(extends v as MobileScreen, animated as Boolean = True, callback as iOSBlock = nil) Declare Sub dismissViewController_ Lib "UIKit.framework" _ Selector "dismissViewControllerAnimated:completion:" _ (viewController As Ptr, animated As Boolean, completion As Ptr) If callback <> Nil Then dismissViewController_(v.ViewControllerHandle, animated, callback.handle) Else dismissViewController_(v.ViewControllerHandle, animated, Nil) End If //Completely close it Declare Sub removeFromParentViewController Lib "UIKit" selector "removeFromParentViewController" (obj As ptr) removeFromParentViewController(v.ViewControllerHandle) End Sub
Function GetBoundsXC(extends v as MobileScreen) As Rect declare function bounds lib "UIKit" selector "bounds" (obj_id as Ptr) as ExtensionsXC.xcCGRect Dim re As ExtensionsXC.xcCGRect = bounds(v.handle) Return New Rect(re.origin.x, re.origin.y, re.rsize.width, re.rsize.height) End Function
Sub HideKeyboardXC(extends v As MobileScreen) Dim myViewPtr As Ptr #if XojoVersion >= 2020.02 myViewPtr = v.Handle #else ' UIKit Declare to get a reference to a View from its ViewController Declare Function decl_GetView Lib "UIKit" selector "view" (aUIViewController As Ptr) As Ptr ' Here is the corresponding Xojo call (View.Self returns a ViewController) myViewPtr = decl_GetView(v.Handle) #endif Declare Sub endEditing Lib "UIKit" selector "endEditing:" (obj_id As ptr, value As Boolean) endEditing(myViewPtr, True) End Sub
Sub HideNavBarShadowXC(extends v As MobileScreen) '[self.navigationController.navigationBar setBackgroundImage:[UIImage new] ' forBarMetrics:UIBarMetricsDefault]; 'self.navigationController.navigationBar.shadowImage = [UIImage new]; 'self.navigationController.navigationBar.translucent = YES; 'self.navigationController.view.backgroundColor = [UIColor clearColor]; 'self.navigationController.navigationBar.backgroundColor = [UIColor clearColor]; Declare Function init Lib "Foundation.framework" selector "init" (obj_id As ptr) As ptr Declare Function alloc Lib "Foundation.framework" selector "alloc" (clsRef As ptr) As ptr Declare Function NSClassFromString Lib "Foundation.framework" (clsName As CFStringRef) As ptr declare function keyWindow lib "UIKit" selector "keyWindow" (obj_ref as ptr) as ptr declare function sharedApplication lib "UIKit" selector "sharedApplication" (obj_ref as ptr) as ptr declare function rootViewController lib "UIKit" selector "rootViewController" (obj_ref as ptr) as ptr declare function navigationBar lib "UIKit" selector "navigationBar" (obj_ref as ptr) as ptr declare function view lib "UIKit.framework" selector "view" (obj_ref as ptr) as ptr declare function navigationController lib "UIKit" selector "navigationController" (viewController as ptr) as ptr dim navigationControllerRef as ptr = navigationController(v.ViewControllerHandle) dim navBar as ptr = navigationBar(navigationControllerRef) 'Dim view As ptr = view(navigationControllerRef) Declare Sub setBackgroundImage Lib "UIKit.Framework" selector "setBackgroundImage:forBarMetrics:" (id As ptr, image As ptr, metrics As Integer) setBackgroundImage(navBar, init(alloc(NSClassFromString("UIImage"))) , 0) Declare sub setShadowImage lib "UIKit.framework" selector "setShadowImage:" (id as ptr, image as ptr) setShadowImage(navBar, init(alloc(NSClassFromString("UIImage")))) End Sub
Sub LayoutIfNeededXC(extends v as MobileScreen) Declare sub layoutIfNeeded Lib "UIKit" selector "layoutIfNeeded" (obj as ptr) layoutIfNeeded(v.Handle) End Sub
Sub PushToSafariControllerXC(extends v as MobileScreen, url as String, BarTintColor as Color = &c000000FF, ControlTintColor as Color = &c000000FF) //New in version 2.0 Declare Function NSClassFromString Lib "Foundation" (className As CFStringRef) As Ptr Declare Function alloc Lib "Foundation.framework" selector "alloc" (clsRef As ptr) As ptr declare function URLWithString_ lib "Foundation.framework" selector "URLWithString:" (clsRef as ptr, URLString as CFStringRef) as ptr Declare function initWithURL_ lib "SafariServices.framework" selector "initWithURL:" (obj as ptr, url as ptr) as ptr Declare Sub presentViewController Lib "UIKit.framework" _ Selector "presentViewController:animated:completion:" _ (parentView As Ptr, viewControllerToPresent As Ptr, animated As Boolean, completion As Ptr) Dim nUrl as ptr = URLWithString_(NSClassFromString("NSURL"), url) Dim svc As ptr = initWithURL_(alloc(NSClassFromString("SFSafariViewController")), nUrl) if BarTintColor.Alpha <> 255 then Declare sub preferredBarTintColor_ lib "UIKit.framework" selector "setPreferredBarTintColor:" (obj as ptr, value as ptr) Dim uic As UIKit.UIColor uic = new UIKit.UIColor(BarTintColor) preferredBarTintColor_(svc, uic) end if if ControlTintColor.Alpha <> 255 then Declare sub preferredControlTintColor_ lib "UIKit.framework" selector "setPreferredControlTintColor:" (obj as ptr, value as ptr) Dim uic As UIKit.UIColor uic = new UIKit.UIColor(ControlTintColor) preferredControlTintColor_(svc, uic) end if presentViewController(v.ViewControllerHandle, svc, True, nil) End Sub
Sub PushToShowModalDissolveXC(extends parent As MobileScreen, v As MobileScreen, style As ViewExtensionsXC.UIModalPresentationStyle = ViewExtensionsXC.UIModalPresentationStyle.fullscreen, Animate As Boolean = True, callback As iOSBlock = Nil) Declare Function NSClassFromString Lib "Foundation" (className As CFStringRef) As Ptr Declare Function alloc Lib "Foundation.framework" selector "alloc" (clsRef As ptr) As ptr Declare Function initWithRootViewController_ Lib "Foundation" selector "initWithRootViewController:" (obj_id As ptr, rootViewController As ptr) As ptr Declare Sub presentViewController Lib "UIKit.framework" _ Selector "presentViewController:animated:completion:" _ (parentView As Ptr, viewControllerToPresent As Ptr, animated As Boolean, completion As Ptr) Declare Sub modalPresentationStyle_ Lib "UIKit.framework" Selector "setModalPresentationStyle:" (obj_id As Ptr, modalPresentationStyle As UIModalPresentationStyle) Declare Sub modalTransitionStyle_ Lib "UIKit.framework" Selector "setModalTransitionStyle:" (obj_id As Ptr, modalTransitionStyle As UIModalTransitionStyle) Dim navController As ptr = initWithRootViewController_( alloc(NSClassFromString("UINavigationController")), v.ViewControllerHandle ) modalPresentationStyle_(navController, style) modalTransitionStyle_(navController, UIModalTransitionStyle.crossDissolve) If callback <> Nil Then Break //This code might fail end if If callback Is Nil Then presentViewController(parent.Handle, navController, Animate, Nil) Else presentViewController(parent.Handle, navController, Animate, callback.handle) End If End Sub
Sub PushToShowModalFlipXC(extends parent As MobileScreen, v As MobileScreen, style As ViewExtensionsXC.UIModalPresentationStyle = ViewExtensionsXC.UIModalPresentationStyle.fullscreen, Animate As Boolean = True, callback As iOSBlock = Nil) Declare Function NSClassFromString Lib "Foundation" (className As CFStringRef) As Ptr Declare Function alloc Lib "Foundation.framework" selector "alloc" (clsRef As ptr) As ptr Declare Function initWithRootViewController_ Lib "Foundation" selector "initWithRootViewController:" (obj_id As ptr, rootViewController As ptr) As ptr Declare Sub presentViewController Lib "UIKit.framework" _ Selector "presentViewController:animated:completion:" _ (parentView As Ptr, viewControllerToPresent As Ptr, animated As Boolean, completion As Ptr) Declare Sub modalPresentationStyle_ Lib "UIKit.framework" Selector "setModalPresentationStyle:" (obj_id As Ptr, modalPresentationStyle As UIModalPresentationStyle) Declare Sub modalTransitionStyle_ Lib "UIKit.framework" Selector "setModalTransitionStyle:" (obj_id As Ptr, modalTransitionStyle As UIModalTransitionStyle) Dim navController As ptr = initWithRootViewController_( alloc(NSClassFromString("UINavigationController")), v.ViewControllerHandle ) modalPresentationStyle_(navController, style) modalTransitionStyle_(navController, UIModalTransitionStyle.flipHorizontal) If callback <> Nil Then Break //This code might fail end if If callback Is Nil Then presentViewController(parent.Handle, navController, Animate, Nil) Else presentViewController(parent.Handle, navController, Animate, callback.handle) End If End Sub
Sub PushToShowModalXC(extends parent As MobileScreen, v As MobileScreen, style As ViewExtensionsXC.UIModalPresentationStyle = ViewExtensionsXC.UIModalPresentationStyle.automatic, Animate As Boolean = True, callback As iOSBlock = Nil, fullModal As Boolean = False) Declare Function NSClassFromString Lib "Foundation" (className As CFStringRef) As Ptr Declare Function alloc Lib "Foundation.framework" selector "alloc" (clsRef As ptr) As ptr Declare Function initWithRootViewController_ Lib "Foundation" selector "initWithRootViewController:" (obj_id As ptr, rootViewController As ptr) As ptr Declare Sub presentViewController Lib "UIKit.framework" _ Selector "presentViewController:animated:completion:" _ (parentView As Ptr, viewControllerToPresent As Ptr, animated As Boolean, completion As Ptr) Declare Sub modalPresentationStyle_ Lib "UIKit.framework" selector "setModalPresentationStyle:" (obj_id As ptr, modalPresentationStyle As UIModalPresentationStyle) Dim navController As ptr = initWithRootViewController_( alloc(NSClassFromString("UINavigationController")), v.ViewControllerHandle ) if (XojoVersion < 2019.03 or ExtensionsXC.GetiOSVersionXC < 13.0) and style = UIModalPresentationStyle.automatic then style = UIModalPresentationStyle.formSheet end if modalPresentationStyle_(navController, style) if fullModal and ExtensionsXC.GetiOSVersionXC >= 13.0 then Declare sub setModalInPresentation lib "UIKit.framework" Selector "setModalInPresentation:" (obj_id as ptr, value as Boolean) setModalInPresentation(navController, true) end if If callback <> Nil Then Break //This code might fail end if If callback Is Nil Then presentViewController(parent.ViewControllerHandle, navController, Animate, Nil) Else presentViewController(parent.ViewControllerHandle, navController, Animate, callback.handle) End If End Sub
Sub SetAnimationsEnabledXC(extends v As MobileScreen, value As Boolean) #Pragma Unused v Declare Function NSClassFromString Lib "Foundation.framework" (clsName As CFStringRef) As ptr Declare sub setAnimationsEnabled lib "UIKit.framework" selector "setAnimationsEnabled:" (obj as ptr, value as boolean) setAnimationsEnabled(NSClassFromString("UIView"), value) End Sub
Sub SetBackgroundColorXC(extends v As MobileScreen, c As Color) Dim uic As UIKit.UIColor if c.Alpha = 255 then uic = UIKit.UIColor.ClearColor else uic = new UIKit.UIColor(c) end if Dim myViewPtr As Ptr #if XojoVersion >= 2020.02 myViewPtr = v.Handle #else ' UIKit Declare to get a reference to a View from its ViewController Declare Function decl_GetView Lib "UIKit" selector "view" (aUIViewController As Ptr) As Ptr ' Here is the corresponding Xojo call (View.Self returns a ViewController) myViewPtr = decl_GetView(v.Handle) #endif ' UIKit Declare to set the backgound color of a View Declare Sub decl_SetBackgroundColor lib "UIKit.framework" selector "setBackgroundColor:" (aUIView As Ptr, aUIColor As Ptr) ' Here is the corresponding Xojo call decl_SetBackgroundColor(myViewPtr, uic) End Sub
Sub SetBackgroundImageXC(extends v As MobileScreen, img As Picture) dim resizedImg As iOSBitmap = new iOSBitmap(v.ContentSize.Width, v.ContentSize.Height, 1) Dim g As iOSGraphics = resizedImg.Graphics dim newW, newH As Integer if g.Height > g.Width then newH = g.Height newW = img.Width/img.Height*newH g.DrawImage(img, (g.Width-newW)/2, 0, newW, newH) else newW = g.Width newH = img.Height/img.Width*newW g.DrawImage(img, 0, (g.Height-newH)/2, newW, newH) end if ' ObjC Declare to get a ref to a class by its name Declare Function objc_getClass lib "/usr/lib/libobjc.dylib" (aClassName As CString) as Ptr ' Here is the corresponding Xojo call dim theUIColorClassRef As Ptr = objc_getClass("UIColor") ' UIKit Declare to create a color object Declare Function decl_GetcolorWithPatternImage Lib "UIKit.framework" selector "colorWithPatternImage:" (UIColorClassRef As Ptr, imgRef As Ptr) As Ptr ' Here is the corresponding Xojo call, where we create a flashy green color Dim myUIColorObject As ptr = decl_GetcolorWithPatternImage(theUIColorClassRef, img.Handle) Dim myViewPtr As Ptr #if XojoVersion >= 2020.02 myViewPtr = v.Handle #else ' UIKit Declare to get a reference to a View from its ViewController Declare Function decl_GetView Lib "UIKit" selector "view" (aUIViewController As Ptr) As Ptr ' Here is the corresponding Xojo call (View.Self returns a ViewController) myViewPtr = decl_GetView(v.Handle) #endif ' UIKit Declare to set the backgound color of a View Declare Sub decl_SetBackgroundColor lib "UIKit.framework" selector "setBackgroundColor:" (aUIView As Ptr, aUIColor As Ptr) ' Here is the corresponding Xojo call decl_SetBackgroundColor(myViewPtr, myUIColorObject) End Sub
Sub SetDisplayModeXC(Extends scr As iOSSplitView, mode As UISplitViewControllerDisplayMode) //Changes the SplitView in portrait mode Declare Sub setPreferredDisplayMode Lib "UIKit" _ selector "setPreferredDisplayMode:" (obj As Ptr, mode As UISplitViewControllerDisplayMode) setPreferredDisplayMode(scr.ViewControllerHandle, mode) End Sub
Sub SetFrameXC(extends tb As MobileToolbarButton, frame As ExtensionsXC.xcCGRect) #Pragma unused tb #pragma unused frame Break //TODO major Doesn't work #If False Declare Sub setFrame Lib "UIKit.framework" selector "setFrame:" (obj_id As ptr, frame As ExtensionsXC.xcCGRect) Declare Function view_ Lib "UIKit.framework" selector "view" (obj_id As ptr) As ptr Dim tbview As ptr = view_(tb.Handle) setFrame(tbview, frame) #EndIf End Sub
Sub SetFullModalXC(extends v As MobileScreen, value As Boolean = True) If ExtensionsxC.GetiOSVersionXC >= 13.0 then Declare sub setModalInPresentation lib "UIKit.framework" Selector "setModalInPresentation:" (obj_id as ptr, value as Boolean) setModalInPresentation(v.ViewControllerHandle, value) end if End Sub
Sub SetHideNavBarOnSwipeXC(extends v As MobileScreen, hide As Boolean) declare function navigationBar lib "UIKit.framework" selector "navigationBar" (obj_ref as ptr) as ptr declare function navigationController lib "UIKit.framework" selector "navigationController" (viewController as ptr) as ptr dim navigationControllerRef as ptr = navigationController(v.ViewControllerHandle) declare sub hidesBarsOnSwipe lib "UIKit.framework" selector "setHidesBarsOnSwipe:" (navcontroller as ptr, value as Boolean) hidesBarsOnSwipe(navigationControllerRef, hide) End Sub
Sub SetHidesBackButtonXC(extends v As MobileScreen, value As Boolean) Declare Function navigationBar Lib "UIKit.framework" selector "navigationBar" (obj_ref As ptr) As ptr Declare Function navigationController Lib "UIKit.framework" selector "navigationController" (viewController As ptr) As ptr 'Dim navigationControllerRef As ptr = navigationController(v.ViewControllerHandle) 'Dim navBar As ptr = navigationBar(navigationControllerRef) Declare Function navigationItem Lib "UIKit.framework" selector "navigationItem" (obj_ref As ptr) As ptr Dim navItem As ptr = navigationItem(v.ViewControllerHandle) Declare Sub hidesBackButton Lib "UIKit.framework" selector "setHidesBackButton:" (obj_id As ptr, value As Boolean) hidesBackButton(navItem, value) End Sub
Sub SetLargeTitleDisplayModeXC(extends v As MobileScreen, mode As ViewExtensionsXC.LargeTitleDisplayMode) Static sSystemVersion As Double //Get sSystemVersion only once If sSystemVersion = 0.0 Then Declare Function NSClassFromString Lib "Foundation" (className As CFStringRef) As Ptr Declare Function currentDevice_ Lib "UIKit.framework" selector "currentDevice" (clsRef As ptr) As ptr Declare Function systemversion_ Lib "UIKit.framework" selector "systemVersion" (obj_id As ptr) As CFStringRef Dim device As Ptr = currentDevice_(NSClassFromString("UIDevice")) Dim systemVersion As String = systemversion_(device) Try sSystemVersion = Double.FromString(systemVersion) Catch End Try End If //Use new API If sSystemVersion >= 11.0 Then 'Declare Function navigationBar Lib "UIKit.framework" selector "navigationBar" (obj_ref As ptr) As ptr 'Declare Function navigationController Lib "UIKit.framework" selector "navigationController" (viewController As ptr) As ptr 'Dim navigationControllerRef As ptr = navigationController(v.ViewControllerHandle) 'Dim navBar As ptr = navigationBar(navigationControllerRef) Declare Function navigationItem Lib "UIKit.framework" selector "navigationItem" (obj_ref As ptr) As ptr Dim navItem As ptr = navigationItem(v.ViewControllerHandle) Declare Sub largeTitleDisplayMode Lib "UIKit.framework" selector "setLargeTitleDisplayMode:" (obj_id As ptr, value As LargeTitleDisplayMode) largeTitleDisplayMode(navItem, mode) Else //Nothing 'Break End If End Sub
Sub SetLargeTitlesXC(extends v as MobileScreen, value as Boolean, displayMode as ViewExtensionsXC.LargeTitleDisplayMode = ViewExtensionsXC.LargeTitleDisplayMode.automatic) Dim sSystemVersion as Double = ExtensionsXC.GetiOSVersionXC //Use new API If sSystemVersion >= 11.0 Then Declare Function navigationBar Lib "UIKit.framework" selector "navigationBar" (obj_ref As ptr) As ptr Declare Function navigationController Lib "UIKit.framework" selector "navigationController" (viewController As ptr) As ptr Dim navigationControllerRef As ptr = navigationController(v.ViewControllerHandle) Dim navBar As ptr = navigationBar(navigationControllerRef) Declare Sub prefersLargeTitles Lib "UIKit.framework" selector "setPrefersLargeTitles:" (obj_id As ptr, value As Boolean) prefersLargeTitles(navBar, value) Declare Function navigationItem Lib "UIKit.framework" selector "navigationItem" (obj_ref As ptr) As ptr Dim navItem As ptr = navigationItem(v.ViewControllerHandle) Dim mode As LargeTitleDisplayMode mode = displayMode Declare Sub largeTitleDisplayMode Lib "UIKit.framework" selector "setLargeTitleDisplayMode:" (obj_id As ptr, value As LargeTitleDisplayMode) largeTitleDisplayMode(navItem, mode) Else #Pragma Unused v #Pragma Unused value #Pragma Unused displayMode End If End Sub
Sub SetNavBarColorXC(extends v As MobileScreen, barColor As color, buttonColor As color, titleColor As Color, translucent As boolean = false, Dark As Boolean = False) declare function NSClassFromString lib "Foundation" (classname as CFStringRef) as ptr Declare Function keyWindow Lib "UIKit.framework" selector "keyWindow" (obj_ref As ptr) As ptr declare function sharedApplication lib "UIKit.framework" selector "sharedApplication" (obj_ref as ptr) as ptr declare function rootViewController lib "UIKit.framework" selector "rootViewController" (obj_ref as ptr) as ptr declare function navigationBar lib "UIKit.framework" selector "navigationBar" (obj_ref as ptr) as ptr declare function navigationController lib "UIKit.framework" selector "navigationController" (viewController as ptr) as ptr dim navigationControllerRef as ptr = navigationController(v.ViewControllerHandle) 'dim sApp as ptr = sharedApplication(NSClassFromString("UIApplication")) dim navBar as ptr = navigationBar(navigationControllerRef) declare sub setTintColor lib "UIKit.framework" selector "setTintColor:" (id as ptr, UIColor as Ptr) setTintColor navBar, new UIColor(buttonColor) declare sub setBarTintColor lib "UIKit.framework" selector "setBarTintColor:" (id as ptr, UIColor as Ptr) Dim uic As UIColor If barColor.Alpha = 255 then uic = UIColor.ClearColor Else uic = new UIColor(barColor) End If setBarTintColor(navBar, uic) declare sub setTranslucent lib "UIKit.framework" selector "setTranslucent:" (id as ptr, value as Boolean) setTranslucent navBar, translucent declare sub setBarStyle lib "UIKit.framework" selector "setBarStyle:" (id as ptr, theStyle as integer) setBarStyle navBar, If(Dark, 1, 0) //UIStatusBarStyleLightContent if ExtensionsXC.GetiOSVersionXC >= 13 then declare function init lib "Foundation.framework" selector "init" (obj_id as ptr) as ptr Declare Function alloc Lib "Foundation.framework" selector "alloc" (clsRef As ptr) As ptr Dim navBarAppearance as ptr = init(alloc(NSClassFromString("UINavigationBarAppearance"))) Declare sub setBackgroundColor lib "UIKit.framework" selector "setBackgroundColor:" (obj as ptr, UIColor as ptr) If barColor.Alpha = 255 then setBackgroundColor navBarAppearance, UIColor.ClearColor Else setBackgroundColor navBarAppearance, new UIColor(barColor) End If Declare Function dictionaryWithObject Lib "Foundation.framework" selector "dictionaryWithObject:forKey:" _ (class_id As Ptr, anObject As ptr, key As CFStringRef) As Ptr Dim constStr As String = ExtensionsXC.StringConstantXC("UIKit", "NSForegroundColorAttributeName") Dim nsDic As Ptr nsDic = DictionaryWithObject(NSClassFromString("NSDictionary"), New UIColor(titleColor), constStr) Declare Sub setTitleTextAttributes Lib "UIKit.framework" selector "setTitleTextAttributes:" _ (obj_id As ptr, att As ptr) setTitleTextAttributes(navBarAppearance, nsDic) Declare Sub setLargeTitleTextAttributes Lib "UIKit.framework" selector "setLargeTitleTextAttributes:" _ (obj_id As ptr, att As ptr) setLargeTitleTextAttributes(navBarAppearance, nsDic) Declare sub setStandardAppearance lib "UIKit.framework" selector "setStandardAppearance:" (obj as ptr, value as ptr) setStandardAppearance(navBar, navBarAppearance) if ExtensionsXC.GetiOSVersionXC >= 15.0 then Declare sub setScrollEdgeAppearance lib "UIKit.framework" selector "setScrollEdgeAppearance:" (obj as ptr, value as ptr) setScrollEdgeAppearance(navBar, navBarAppearance) end if end if End Sub
Sub SetNavBarTintColorXC(extends screen As MobileScreen, tintColor As Color) //New in version 2.0 declare function navigationBar lib "UIKit.framework" selector "navigationBar" (obj_ref as ptr) as ptr declare function navigationController lib "UIKit.framework" selector "navigationController" (viewController as ptr) as ptr dim navigationControllerRef as ptr = navigationController(screen.ViewControllerHandle) dim navBar as ptr = navigationBar(navigationControllerRef) declare sub setTintColor lib "UIKit.framework" selector "setTintColor:" (id as ptr, UIColor as Ptr) setTintColor navBar, new UIColor(tintColor) End Sub
Sub SetNavBarTitleColorXC(extends v As MobileScreen, value As Color) Declare Function navigationBar Lib "UIKit.framework" selector "navigationBar" (obj_ref As ptr) As ptr Declare Function navigationController Lib "UIKit.framework" selector "navigationController" (viewController As ptr) As ptr Dim navigationControllerRef As ptr = navigationController(v.ViewControllerHandle) Dim navBar As ptr = navigationBar(navigationControllerRef) Declare Function NSClassFromString Lib "Foundation" (name As CFStringRef) As Ptr Declare Function dictionaryWithObject Lib "Foundation.framework" selector "dictionaryWithObject:forKey:" _ (class_id As Ptr, anObject As Ptr, key As CFStringRef) As Ptr Dim constStr As String = ExtensionsXC.StringConstantXC("UIKit", "NSForegroundColorAttributeName") Dim constRef As CFStringRef = constStr Dim nsDic As Ptr nsDic = DictionaryWithObject(NSClassFromString("NSDictionary"), New UIColor(value), constStr) Declare Sub setTitleTextAttributes Lib "UIKit.framework" selector "setTitleTextAttributes:" _ (obj_id As ptr, att As ptr) setTitleTextAttributes(navBar, nsDic) if ExtensionsXC.GetiOSVersionXC >= 13 then declare function init lib "Foundation.framework" selector "init" (obj_id as ptr) as ptr Declare Function alloc Lib "Foundation.framework" selector "alloc" (clsRef As ptr) As ptr Declare Sub setTitleTextAttributes Lib "UIKit.framework" selector "setTitleTextAttributes:" _ (obj_id As ptr, att As ptr) Declare Sub setLargeTitleTextAttributes Lib "UIKit.framework" selector "setLargeTitleTextAttributes:" _ (obj_id As ptr, att As ptr) Declare Function getStandardAppearance lib "UIKit.framework" selector "standardAppearance" (obj as ptr) as ptr Declare sub setStandardAppearance lib "UIKit.framework" selector "setStandardAppearance:" (obj as ptr, value as ptr) Dim navBarAppearance as ptr navBarAppearance = getStandardAppearance(navBar) if navBarAppearance = nil then navBarAppearance = init(alloc(NSClassFromString("UINavigationBarAppearance"))) end if setTitleTextAttributes(navBarAppearance, nsDic) setLargeTitleTextAttributes(navBarAppearance, nsDic) setStandardAppearance(navBar, navBarAppearance) if ExtensionsXC.GetiOSVersionXC >= 15.0 then Declare sub setScrollEdgeAppearance lib "UIKit.framework" selector "setScrollEdgeAppearance:" (obj as ptr, value as ptr) setScrollEdgeAppearance(navBar, navBarAppearance) end if end if End Sub
Sub SetNavBarTitleControlXC(extends v As MobileScreen, ctrl As MobileUIControl) declare function navigationController lib "UIKit.framework" selector "navigationController" (viewController as ptr) as ptr declare function navigationBar lib "UIKit.framework" selector "navigationBar" (obj_ref as ptr) as ptr declare function topItem lib "UIKit.framework" selector "topItem" (id as ptr) as ptr Declare Sub setTitleView Lib "UIKit.framework" selector "setTitleView:" (id As ptr, UIImage As Ptr) Declare Function NSClassFromString Lib "Foundation" (className As CFStringRef) As Ptr declare Function alloc lib "Foundation" selector "alloc"(classPtr as Ptr) as Ptr Declare function initWithImage lib "UIKit.framework" selector "initWithImage:" (objRef as Ptr, imgRef as Ptr) as Ptr //Reference to Navigation Controller dim navigationControllerRef as ptr = navigationController(v.ViewControllerHandle) //Ref to NavigationBar dim navBar as ptr = navigationBar(navigationControllerRef) //Ref to Title item dim navItem as ptr = topItem(navBar) //Set Title item to use the control setTitleView(navItem, ctrl.Handle) End Sub
Sub SetNavBarTitleImageXC(extends v As MobileScreen, image As Picture) declare function navigationController lib "UIKit.framework" selector "navigationController" (viewController as ptr) as ptr declare function navigationBar lib "UIKit.framework" selector "navigationBar" (obj_ref as ptr) as ptr declare function topItem lib "UIKit.framework" selector "topItem" (id as ptr) as ptr Declare Sub setTitleView Lib "UIKit.framework" selector "setTitleView:" (id As ptr, UIImage As Ptr) Declare Function NSClassFromString Lib "Foundation" (className As CFStringRef) As Ptr declare Function alloc lib "Foundation" selector "alloc"(classPtr as Ptr) as Ptr Declare function initWithImage lib "UIKit.framework" selector "initWithImage:" (objRef as Ptr, imgRef as Ptr) as Ptr //Reference to Navigation Controller dim navigationControllerRef as ptr = navigationController(v.ViewControllerHandle) //Ref to NavigationBar dim navBar as ptr = navigationBar(navigationControllerRef) //Ref to Title item dim navItem as ptr = topItem(navBar) //Create imageView with the passed image Dim imgHandle As Ptr if image.Handle = nil then imgHandle = image.CopyOSHandle(Picture.HandleType.iOSUIImage) else imgHandle = image.handle end if Dim iView As Ptr = initWithImage( alloc( NSClassFromString("UIImageView")), imgHandle) //Set Title item to use the imageView setTitleView(navItem, iView) End Sub
Sub SetNavBarTranslucentXC(extends v As MobileScreen, value As Boolean) //New in version 2.0 '[self.navigationController.navigationBar setBackgroundImage:[UIImage new] ' forBarMetrics:UIBarMetricsDefault]; 'self.navigationController.navigationBar.shadowImage = [UIImage new]; 'self.navigationController.navigationBar.translucent = YES; 'self.navigationController.view.backgroundColor = [UIColor clearColor]; 'self.navigationController.navigationBar.backgroundColor = [UIColor clearColor]; Declare Function NSClassFromString Lib "Foundation.framework" (clsName As CFStringRef) As ptr Declare Function alloc Lib "Foundation.framework" selector "alloc" (clsRef As Ptr) As ptr Declare Function init Lib "Foundation.framework" selector "init" (obj_id As ptr) As ptr declare function keyWindow lib "UIKit.framework" selector "keyWindow" (obj_ref as ptr) as ptr declare function sharedApplication lib "UIKit.framework" selector "sharedApplication" (obj_ref as ptr) as ptr declare function rootViewController lib "UIKit.framework" selector "rootViewController" (obj_ref as ptr) as ptr declare function navigationBar lib "UIKit.framework" selector "navigationBar" (obj_ref as ptr) as ptr declare function navigationController lib "UIKit.framework" selector "navigationController" (viewController as ptr) as ptr dim navigationControllerRef as ptr = navigationController(v.ViewControllerHandle) dim navBar as ptr = navigationBar(navigationControllerRef) 'Dim view As ptr = view(navigationControllerRef) declare sub setTranslucent lib "UIKit.framework" selector "setTranslucent:" (id as ptr, value as Boolean) setTranslucent navBar, value End Sub
Sub SetNavBarTransparentXC(extends v As MobileScreen) '[self.navigationController.navigationBar setBackgroundImage:[UIImage new] ' forBarMetrics:UIBarMetricsDefault]; 'self.navigationController.navigationBar.shadowImage = [UIImage new]; 'self.navigationController.navigationBar.translucent = YES; 'self.navigationController.view.backgroundColor = [UIColor clearColor]; 'self.navigationController.navigationBar.backgroundColor = [UIColor clearColor]; Declare Function NSClassFromString Lib "Foundation.framework" (clsName As CFStringRef) As ptr Declare Function alloc Lib "Foundation.framework" selector "alloc" (clsRef As Ptr) As ptr Declare Function init Lib "Foundation.framework" selector "init" (obj_id As ptr) As ptr declare function keyWindow lib "UIKit.framework" selector "keyWindow" (obj_ref as ptr) as ptr declare function sharedApplication lib "UIKit.framework" selector "sharedApplication" (obj_ref as ptr) as ptr declare function rootViewController lib "UIKit.framework" selector "rootViewController" (obj_ref as ptr) as ptr declare function navigationBar lib "UIKit.framework" selector "navigationBar" (obj_ref as ptr) as ptr Declare Function view Lib "UIKit.framework" selector "view" (obj_ref As ptr) As ptr declare function navigationController lib "UIKit.framework" selector "navigationController" (viewController as ptr) as ptr dim navigationControllerRef as ptr = navigationController(v.ViewControllerHandle) dim navBar as ptr = navigationBar(navigationControllerRef) 'Dim view As ptr = view(navigationControllerRef) Declare sub setBackgroundImage lib "UIKit.framework" selector "setBackgroundImage:forBarMetrics:" (id as ptr, image as ptr, metrics as Integer) setBackgroundImage(navBar, init(alloc(NSClassFromString("UIImage"))) , 0) Declare sub setShadowImage lib "UIKit.framework" selector "setShadowImage:" (id as ptr, image as ptr) setShadowImage(navBar, init(alloc(NSClassFromString("UIImage")))) declare sub setTranslucent lib "UIKit.framework" selector "setTranslucent:" (id as ptr, value as Boolean) setTranslucent navBar, True declare sub setBarStyle lib "UIKit.framework" selector "setBarStyle:" (id as ptr, theStyle as integer) setBarStyle navBar, 1 //UIStatusBarStyleLightContent if ExtensionsXC.GetiOSVersionXC >= 13 then Declare function standardAppearance lib "UIKit.framework" selector "standardAppearance" (obj as ptr) as ptr Dim navBarAppearance as ptr = standardAppearance(navBar) Declare sub setBackgroundColor lib "UIKit.framework" selector "setBackgroundColor:" (obj as ptr, UIColor as ptr) setBackgroundColor navBarAppearance, UIColor.ClearColor declare sub configureWithTransparentBackground lib "UIKit.framework" selector "configureWithTransparentBackground" (obj as ptr) configureWithTransparentBackground(navBarAppearance) Declare sub setStandardAppearance lib "UIKit.framework" selector "setStandardAppearance:" (obj as ptr, value as ptr) setStandardAppearance(navBar, navBarAppearance) if ExtensionsXC.GetiOSVersionXC >= 15.0 then Declare sub setScrollEdgeAppearance lib "UIKit.framework" selector "setScrollEdgeAppearance:" (obj as ptr, value as ptr) setScrollEdgeAppearance(navBar, navBarAppearance) end if end if End Sub
Sub SetOverrideUserInterfaceStyleXC(extends v As MobileScreen, style As ControlExtensionsXC.UIUserInterfaceStyle) if ExtensionsXC.GetiOSVersionXC >= 13.0 then declare sub overrideUserInterfaceStyle lib "UIKit.framework" selector "setOverrideUserInterfaceStyle:" (obj as ptr, style As ControlExtensionsXC.UIUserInterfaceStyle) overrideUserInterfaceStyle(v.Handle, style) end if End Sub
Sub SetPreferredContentSizeXC(extends v As MobileScreen, sz As Size) Dim aSize As ExtensionsXC.xcCGSize aSize.width = sz.Width aSize.height = sz.Height Declare sub setPreferredContentSize lib "UIKit" Selector "setPreferredContentSize:" (obj as ptr, value as ExtensionsXC.xcCGSize) setPreferredContentSize(v.ViewControllerHandle, aSize) End Sub
Sub SetStatusBarStyleXC(extends v As MobileScreen, style As AppExtensionsXC.UIStatusBarStyle) #Pragma Unused v Declare Function NSClassFromString Lib "Foundation" (className As CFStringRef) As Ptr Declare Function sharedApplication Lib "UIKit" Selector "sharedApplication" (obj As Ptr) As Ptr Declare sub setStatusBarStyle lib "UIKit" selector "setStatusBarStyle:" (obj as ptr, style as AppExtensionsXC.UIStatusBarStyle) Dim sharedApp As Ptr = sharedApplication(NSClassFromString("UIApplication")) setStatusBarStyle(sharedApp, style) End Sub
Sub SetTintColorXC(extends tb As MobileToolbarButton, value As Color) Declare Sub setTintColor Lib "UIKit.framework" selector "setTintColor:" (id As ptr, UIColor As Ptr) setTintColor tb.handle, New UIColor(value) End Sub
Sub SetToolBarBackgroundColorXC(extends v as MobileScreen, barColor as color, translucent as boolean = false) Declare Function toolbar_ Lib "UIKit.framework" selector "toolbar" (o As Ptr) As Ptr Declare Function navigationController Lib "UIKit" selector "navigationController" (viewController As ptr) As ptr Dim navigationControllerRef As ptr = navigationController(v.ViewControllerHandle) Dim toolbar As Ptr = toolbar_(navigationControllerRef) Declare Sub setBarTintColor Lib "UIKit.framework" selector "setBarTintColor:" (id As ptr, UIColor As Ptr) setBarTintColor toolbar, New UIColor(barColor) if translucent then declare sub setTranslucent lib "UIKit.framework" selector "setTranslucent:" (id as ptr) setTranslucent toolbar end End Sub
Sub SetToolBarColorXC(extends v as MobileScreen, barColor as color) Declare Function toolbar_ Lib "UIKit.framework" selector "toolbar" (o As Ptr) As Ptr Declare Function navigationController Lib "UIKit" selector "navigationController" (viewController As ptr) As ptr Dim navigationControllerRef As ptr = navigationController(v.ViewControllerHandle) Dim toolbar As Ptr = toolbar_(navigationControllerRef) Declare Sub tintColor_ Lib "UIKit.framework" selector "setTintColor:" (obj_id As ptr, tintColor As ptr) tintColor_ toolbar, New UIColor(barColor) End Sub
Sub SetUserInterfaceStyleXC(extends screen as MobileScreen, value as ControlExtensionsXC.UIUserInterfaceStyle) if ExtensionsXC.GetiOSVersionXC >= 13.4 then Declare sub overrideUserInterfaceStyle lib "UIKit" selector "setOverrideUserInterfaceStyle:" (obj as ptr, value as ControlExtensionsXC.UIUserInterfaceStyle) overrideUserInterfaceStyle(screen.handle, value) end if End Sub
Sub ShowSheetXC(extends v As MobileScreen, parentScreen As MobileScreen, height As UISheetPresentationControllerDetent = UISheetPresentationControllerDetent.large, showGrabber As Boolean = False, Animate As Boolean = True) //Source https://sarunw.com/posts/bottom-sheet-in-ios-15-with-uisheetpresentationcontroller/ if ExtensionsXC.GetiOSVersionXC < 15.0 then Dim err As new UnsupportedOperationException err.Reason = CurrentMethodName + " requires iOS15+" Raise err end if Declare Function NSClassFromString Lib "Foundation" (className As CFStringRef) As Ptr Declare Function alloc Lib "Foundation.framework" selector "alloc" (clsRef As ptr) As ptr Declare Function initWithRootViewController_ Lib "Foundation" selector "initWithRootViewController:" (obj_id As ptr, rootViewController As ptr) As ptr Declare Sub presentViewController Lib "UIKit.framework" _ Selector "presentViewController:animated:completion:" _ (parentView As Ptr, viewControllerToPresent As Ptr, animated As Boolean, completion As Ptr) Declare Sub modalPresentationStyle_ Lib "UIKit.framework" selector "setModalPresentationStyle:" (obj_id As ptr, modalPresentationStyle As UIModalPresentationStyle) Declare Function sheetPresentationController lib "UIKit" selector "sheetPresentationController" (obj as ptr) as ptr Declare sub setDetents lib "UIKit" selector "setDetents:" (obj as ptr, value as ptr) Declare Function init Lib "Foundation.framework" selector "init" (obj_id As ptr) As ptr Declare function largeDetent_ lib "UIKit" selector "largeDetent" (obj as ptr) as ptr Declare function mediumDetent_ lib "UIKit" selector "mediumDetent" (obj as ptr) as ptr Dim navController As ptr = initWithRootViewController_( alloc(NSClassFromString("UINavigationController")), v.ViewControllerHandle ) Dim style As ViewExtensionsXC.UIModalPresentationStyle style = UIModalPresentationStyle.pageSheet modalPresentationStyle_(navController, style) Dim sheet As Ptr = sheetPresentationController(navController) if sheet <> nil then Declare Function arrayWithCapacity Lib "Foundation" selector "arrayWithCapacity:" (cls As ptr, count as UInteger) As ptr Declare Sub addObject Lib "Foundation" selector "addObject:" (arr As ptr, obj As ptr) Dim detentArray As ptr Select case height Case UISheetPresentationControllerDetent.medium detentArray = arrayWithCapacity(NSClassFromString("NSMutableArray"), 1) Dim mediumDetent As Ptr = mediumDetent_(NSClassFromString("UISheetPresentationControllerDetent")) addObject(detentArray, mediumDetent) Case UISheetPresentationControllerDetent.large detentArray = arrayWithCapacity(NSClassFromString("NSMutableArray"), 1) 'Dim largeDetent As Ptr = largeDetent_(init(alloc(NSClassFromString("UISheetPresentationControllerDetent")))) Dim largeDetent As Ptr = largeDetent_(NSClassFromString("UISheetPresentationControllerDetent")) addObject(detentArray, largeDetent) Case UISheetPresentationControllerDetent.medium_large detentArray = arrayWithCapacity(NSClassFromString("NSMutableArray"), 1) Dim mediumDetent As Ptr = mediumDetent_(((NSClassFromString("UISheetPresentationControllerDetent")))) Dim largeDetent As Ptr = largeDetent_(((NSClassFromString("UISheetPresentationControllerDetent")))) addObject(detentArray, mediumDetent) addObject(detentArray, largeDetent) End Select setDetents(sheet, detentArray) //Grabber if showGrabber then declare sub setPrefersGrabberVisible lib "UIKit" selector "setPrefersGrabberVisible:" (obj as ptr, value as Boolean) setPrefersGrabberVisible(sheet, True) end if end if presentViewController(parentScreen.ViewControllerHandle, navController, Animate, Nil) End Sub
Protected Sub TransitionWithViewDurationOptionsXC(ctrl as MobileUIControl, duration as Double, options as Integer, animationBlock as iOSBlock, completion as iOSBlock = nil) https://developer.apple.com/documentation/uikit/uiview/1622574-transitionwithview Dim classPtr As ptr Declare sub transition_ lib "UIKit" selector "transitionWithView:duration:options:animations:completion:" _ (id as ptr, view as ptr, duration as Double, options as Integer, animations as ptr, completion as ptr) Declare sub animateWithDuration_ lib "UIKit" selector "animateWithDuration:animations:completion:" _ (id as ptr, duration as Double, animations as ptr, completion as ptr) declare function NSClassFromString lib "Foundation" (clsName as cfstringref) as ptr #if False UIView transitionWithView:textFieldimageView duration:0.2f options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ imageView.image = newImage; } completion:nil]; #endif classPtr = NSClassFromString("UIView") if completion is nil then transition_ classPtr, ctrl.Handle, duration, options, animationBlock.Handle, nil 'animateWithDuration_ classptr, duration, animationBlock.handle, nil else transition_ classPtr, ctrl.Handle, duration, options, animationBlock.Handle, completion.Handle end if End Sub
Function isRightToLeftXC(extends view As MobileScreen) As Boolean Const UIUserInterfaceLayoutDirectionLeftToRight = 0 Const UIUserInterfaceLayoutDirectionRightToLeft = 1 Declare Function NSClassFromString Lib "Foundation" (className As CFStringRef) As Ptr Declare function userInterfaceLayoutDirection_ lib "UIKit" selector "userInterfaceLayoutDirectionForSemanticContentAttribute:" _ (obj_ref as ptr, attribute as ptr) as UIUserInterfaceLayoutDirection Declare function semanticContentAttribute_ lib "UIKit" selector "semanticContentAttribute" (obj_ref as ptr) as ptr Dim myViewPtr As Ptr #if XojoVersion >= 2020.02 myViewPtr = view.Handle #else ' UIKit Declare to get a reference to a View from its ViewController Declare Function decl_GetView Lib "UIKit" selector "view" (aUIViewController As Ptr) As Ptr ' Here is the corresponding Xojo call (View.Self returns a ViewController) myViewPtr = decl_GetView(view.Handle) #endif if userInterfaceLayoutDirection_(NSClassFromString("UIView"), semanticContentAttribute_(myViewPtr)) = UIUserInterfaceLayoutDirection.rightToLeft then Return True end if End Function
End Module
Module HTMLViewerExtensionsXC
Delegate Protected Sub ExecuteJavascriptDelegateXC(result As Variant, error As RuntimeException)
Sub ExecuteJavascriptXC(Extends viewer As MobileHTMLViewer, script As String, callback As ExecuteJavascriptDelegateXC = nil) //Code from Jason King // https://forum.xojo.com/19271-ios-what-we-want-roadmap/p2#p169870 Declare Sub execJavaScript Lib "WebKit.framework" selector "evaluateJavaScript:completionHandler:" (obj_id As ptr, script As CFStringRef, block As ptr) If callback <> Nil Then ExecuteJavascriptCallback = callback Dim block As New iOSBlock(AddressOf ExecuteJavascript_Result) execJavaScript(viewer.Handle, script, block.Handle) Else execJavaScript(viewer.Handle, script, Nil) End If End Sub
Private Sub ExecuteJavascript_Result(result As ptr, error As ptr) If error <> Nil Then Declare Function localizedDescription Lib "Foundation.framework" selector "localizedDescription" (obj_id As ptr) As CFStringRef Dim errReason As String = localizedDescription(error) Dim err As New RuntimeException err.Message = errReason //Sending the error and returning Try If ExecuteJavascriptCallback <> Nil Then ExecuteJavascriptCallback.Invoke(Nil, err) End If Catch End Try Return End If Declare Function NSClassFromString Lib "Foundation.framework" (clsName As CFStringRef) As ptr Declare Function isKindOfClass Lib "UIKit.framework" selector "isKindOfClass:" (obj_id As ptr, cls As ptr) As Boolean Dim value As Auto //Finding type of result //This is a tricky part If isKindOfClass(result, NSClassFromString("NSString")) Then Dim tmp As String Declare Function self_ Lib "Foundation.framework" selector "self" (obj_id As ptr) As CFStringRef tmp = self_(result) value = tmp 'Declare Function stringWithString Lib "Foundation.framework" selector "stringWithString:" (clsRef As ptr, Str As ptr) As CFStringRef 'Dim t As Text = stringWithString(NSClassFromString("NSString"), result) 'value = t Elseif isKindOfClass(result, NSClassFromString("NSNumber")) Then Declare Function CFNumberGetValue Lib "Foundation.framework" (number As Ptr, theType As Integer, ByRef valuePtr As CGFloat) As Boolean Const kCFNumberCGFloatType = 16 Dim d As Double Call CFNumberGetValue(result, kCFNumberCGFloatType, d) value = d 'Declare Function doubleValue Lib "Foundation.framework" selector "doubleValue:" (clsRef As ptr, Val As ptr) As CGFloat ' 'Dim d As Double = DoubleValue(NSClassFromString("NSNumber"), result) ' 'value = d //ObjC function might return different value types 'Elseif isKindOfClass(obj, Foundation.NSClassFromString("NSDictionary")) Then 'Return "NSDictionary" 'Elseif isKindOfClass(obj, Foundation.NSClassFromString("NSArray")) Then 'Return "NSArray" Else value = result End If //Invoking callback with result Try If ExecuteJavascriptCallback <> Nil Then ExecuteJavascriptCallback.Invoke(value, Nil) End If Catch End Try ExecuteJavascriptCallback = Nil End Sub
Sub LoadFileXC(extends viewer As MobileHTMLViewer, htmlFile As FolderItem) Declare Function NSClassFromString Lib "Foundation.framework" (clsName As CFStringRef) As ptr Declare Function URLWithString Lib "Foundation.framework" Selector "URLWithString:" ( id As Ptr, URLString As CFStringRef ) As Ptr Declare sub loadFileURL lib "UIKit.framework" selector "loadFileURL:allowingReadAccessToURL:" (obj as ptr, url as ptr, readAccessURL as ptr) Dim fileURL As Ptr = URLWithString(NSClassFromString("NSURL"), htmlFile.URLPath) Dim parentURL As Ptr = URLWithString(NSClassFromString("NSURL"), htmlFile.parent.URLPath) loadFileURL(viewer.Handle, fileURL, parentURL) End Sub
Sub LoadPageXC(extends viewer As MobileHTMLViewer, html As String, baseURL As String = "") //Code from Jason King // https://forum.xojo.com/19271-ios-what-we-want-roadmap/p2#p169870 Declare Sub loadHTML Lib "UIKit.framework" selector "loadHTMLString:baseURL:" (obj_id As ptr, html As CFStringRef, url As ptr) If baseURL.isEmpty Then loadHTML(viewer.handle, html, Nil) Else Declare Function NSClassFromString Lib "Foundation.framework" (clsName As CFStringRef) As ptr Declare Function URLWithString Lib "Foundation" Selector "URLWithString:" ( id As Ptr, URLString As CFStringRef ) As Ptr Dim nsURL As Ptr = URLWithString(NSClassFromString("NSURL"), baseURL) loadHTML(viewer.Handle, html, nsURL) End If End Sub
Sub SetTransparentXC(extends viewer As MobileHTMLViewer, value As Boolean) //New 'self.webView!.isOpaque = false 'self.webView!.backgroundColor = UIColor.clear 'self.webView!.scrollView.backgroundColor = UIColor.clear declare sub setOpaque lib "UIKit.framework" selector "setOpaque:" (id as ptr, value as Boolean) if value then setOpaque(viewer.Handle, not value) viewer.SetBackgroundColorXC(&c000000FF) Else setOpaque(viewer.Handle, not value) viewer.SetBackgroundColorXC(&cFFFFFF) end if End Sub
Sub UserAgentXC(extends viewer As MobileHTMLViewer, callback As HTMLViewerExtensionsXC.ExecuteJavascriptDelegateXC) viewer.ExecuteJavascriptXC("navigator.userAgent", callback) End Sub
Property Protected ExecuteJavascriptCallback As ExecuteJavascriptDelegateXC
End Module
Module UIKit
Const UIKitLib = UIKit.framework
Note "README"
Delete this module if you are already using iOSKit by Jason King
End Module
Class UIColor
Delegate Private Function ClassMethodDelegate(class_id as Ptr) As Ptr
Function CGColor() As Ptr Declare Function CGColor Lib UIKitLib selector "cgColor" (obj_id As ptr) as ptr Return CGColor(self) End Function
Shared Function ClearColor() As UIColor return MakeObjectFromClassMethod(AddressOf m_clearColor) End Function
Function ColorValue() As Color //FIX: does not return the correct color declare function getComponents lib "UIKit.framework" selector "getRed:green:blue:alpha:" (obj_id as ptr, red as CGFloat, green as CGFloat, blue as CGFloat, alpha as CGFloat) as Boolean dim r, g, b, a as Single dim success as Boolean = getComponents(self, r,g,b,a) if success then Return Color.RGB(r*255,g*255,b*255) end if Break Return Color.Black End Function
Sub Constructor(fromColor as Color) // Calling the overridden superclass constructor. // Note that this may need modifications if there are multiple constructor choices. // Possible constructor calls: // Constructor() -- From NSObject // Constructor(ref as ptr) -- From NSObject self.Constructor(fromColor.red,fromColor.Green, fromColor.Blue, fromColor.Alpha) End Sub
Sub Constructor(red as Integer, green as integer, blue as Integer, alpha as Integer) // Calling the overridden superclass constructor. // Note that this may need modifications if there are multiple constructor choices. // Possible constructor calls: // Constructor() -- From NSObject // Constructor(ref as ptr) -- From NSObject Declare Function NSClassFromString Lib "Foundation" (className As CFStringRef) As Ptr Declare Function alloc Lib "Foundation.framework" selector "alloc" (clsRef As ptr) As ptr Declare Function initWithComponents Lib "UIKit.framework" selector "initWithRed:green:blue:alpha:" _ (obj_id as ptr, red as CGFloat, green as CGFloat, blue as CGFloat, alpha as CGFloat) as ptr Self.Constructor(initWithComponents(alloc(NSClassFromString("UIColor")),red/255,green/255,blue/255,(255-alpha)/255)) needsExtraRelease = True End Sub
Sub Constructor(ref as ptr) declare function retain lib "UIKit.framework" selector "retain" (obj_id as ptr) as ptr m_id = retain(ref) End Sub
Shared Function Cyan() As UIColor return MakeObjectFromClassMethod(AddressOf m_cyanColor) End Function
Shared Function DarkGray() As UIColor return MakeObjectFromClassMethod(AddressOf m_darkGrayColor) End Function
Sub Destructor() declare sub release lib UIKitLib selector "release" (obj_id as ptr) release(m_id) if needsExtraRelease then release(m_id) End Sub
Shared Function Gray() As UIColor return MakeObjectFromClassMethod(AddressOf m_grayColor) End Function
Shared Function Green() As UIColor return MakeObjectFromClassMethod(AddressOf m_greenColor) End Function
Shared Function LightGray() As UIColor return MakeObjectFromClassMethod(AddressOf m_lightGrayColor) End Function
Shared Function Magenta() As UIColor return MakeObjectFromClassMethod(AddressOf m_magentaColor) End Function
Private Shared Function MakeObjectFromClassMethod(d as ClassMethodDelegate) As UIColor Declare Function NSClassFromString Lib "Foundation" (className As CFStringRef) As Ptr Return New UIColor(d.Invoke(NSClassFromString("UIColor"))) #pragma unused d End Function
Function Operator_Convert() As ptr return self.id End Function
Shared Function Orange() As UIColor return MakeObjectFromClassMethod(AddressOf m_orangeColor) End Function
Shared Function Purple() As UIColor return MakeObjectFromClassMethod(AddressOf m_purpleColor) End Function
Shared Function Red() As UIColor return MakeObjectFromClassMethod(AddressOf m_redColor) End Function
Shared Function White() As UIColor return MakeObjectFromClassMethod(AddressOf m_whiteColor) End Function
Shared Function Yellow() As UIColor return MakeObjectFromClassMethod(AddressOf m_yellowColor) End Function
Function id() As ptr Return self.m_id End Function
Private Shared Function m_blackColor(class_id as Ptr) As Ptr declare function blackColor lib UIKitLib selector "blackColor" (id as Ptr) as Ptr return blackColor(class_id) #pragma unused class_id End Function
Private Shared Function m_blueColor(class_id as Ptr) As Ptr declare function blueColor lib UIKitLib selector "blueColor" (id as Ptr) as Ptr return blueColor(class_id) #pragma unused class_id End Function
Private Shared Function m_brownColor(class_id as Ptr) As Ptr declare function brownColor lib UIKitLib selector "brownColor" (id as Ptr) as Ptr return brownColor(class_id) #pragma unused class_id End Function
Private Shared Function m_clearColor(class_id as Ptr) As Ptr declare function clearColor lib UIKitLib selector "clearColor" (id as Ptr) as Ptr return clearColor(class_id) #pragma unused class_id End Function
Private Shared Function m_cyanColor(class_id as Ptr) As Ptr declare function cyanColor lib UIKitLib selector "cyanColor" (id as Ptr) as Ptr return cyanColor(class_id) #pragma unused class_id End Function
Private Shared Function m_darkGrayColor(class_id as Ptr) As Ptr declare function darkGrayColor lib UIKitLib selector "darkGrayColor" (id as Ptr) as Ptr return darkGrayColor(class_id) #pragma unused class_id End Function
Private Shared Function m_grayColor(class_id as Ptr) As Ptr declare function grayColor lib UIKitLib selector "grayColor" (id as Ptr) as Ptr return grayColor(class_id) #pragma unused class_id End Function
Private Shared Function m_greenColor(class_id as Ptr) As Ptr declare function greenColor lib UIKitLib selector "greenColor" (id as Ptr) as Ptr return greenColor(class_id) #pragma unused class_id End Function
Private Shared Function m_lightGrayColor(class_id as Ptr) As Ptr declare function lightGrayColor lib UIKitLib selector "lightGrayColor" (id as Ptr) as Ptr return lightGrayColor(class_id) #pragma unused class_id End Function
Private Shared Function m_magentaColor(class_id as Ptr) As Ptr declare function magentaColor lib UIKitLib selector "magentaColor" (id as Ptr) as Ptr return magentaColor(class_id) #pragma unused class_id End Function
Private Shared Function m_orangeColor(class_id as Ptr) As Ptr declare function orangeColor lib UIKitLib selector "orangeColor" (id as Ptr) as Ptr return orangeColor(class_id) #pragma unused class_id End Function
Private Shared Function m_purpleColor(class_id as Ptr) As Ptr declare function purpleColor lib UIKitLib selector "purpleColor" (id as Ptr) as Ptr return purpleColor(class_id) #pragma unused class_id End Function
Private Shared Function m_redColor(class_id as Ptr) As Ptr declare function redColor lib UIKitLib selector "redColor" (id as Ptr) as Ptr return redColor(class_id) #pragma unused class_id End Function
Private Shared Function m_whiteColor(class_id as Ptr) As Ptr declare function whiteColor lib UIKitLib selector "whiteColor" (id as Ptr) as Ptr return whiteColor(class_id) #pragma unused class_id End Function
Private Shared Function m_yellowColor(class_id as Ptr) As Ptr declare function yellowColor lib UIKitLib selector "yellowColor" (id as Ptr) as Ptr return yellowColor(class_id) #pragma unused class_id End Function
Property Private m_id As ptr
Property Protected needsExtraRelease As Boolean = false
End Class
Module TabBarExtensionsXC
Protected Function GetTabPageXC() As Integer 'This method has been posted in the forum by Antonio Rinaldi. 'It allows setting the active tab like if the user had tapped himself on the tab icon, without need for PushTo. 'Index is zero based, left to right 'Sub goTabPage(idx as integer,doReset as Boolean=False) Declare Function NSClassFromString Lib "Foundation"(cls As CFStringRef) As Ptr Declare Function sharedApplication_ Lib "UIKit" selector "sharedApplication"(cls_ptr As Ptr) As Ptr Dim shAppPtr As Ptr=sharedApplication_(NSClassFromString("UIApplication")) Declare Function keyWindow_ Lib "UIkit" selector "keyWindow"(app_ptr As Ptr) As Ptr Dim keyWinPtr As Ptr=keyWindow_(shAppPtr) Declare Function rootWiewController_ Lib "UIKit" selector "rootViewController"(winPtr As Ptr) As Ptr Dim rootWiewControllerPtr As Ptr=rootWiewController_(keyWinPtr) Declare Function isMemberOfClass_ Lib "foundation" selector "isMemberOfClass:"(oPtr As Ptr,cPtr As Ptr) As Boolean Dim a As ptr a=NSClassFromString("UITabBarController") If isMemberOfClass_(rootWiewControllerPtr,NSClassFromString("UITabBarController")) Then Declare Function getSelectedIndex Lib "UIKIT" selector "selectedIndex"(tbPtr As Ptr) as UInteger return getSelectedIndex(rootWiewControllerPtr) End If Return -1 End Function
Sub PushToHideTabBarXC(extends parentView As MobileScreen, childView As MobileScreen) ' This method was posted by Paul Lefebvre at https://forum.xojo.com/18176-controlling-tab-bar-visibility/last ' on 12/12/2014 'To hide the tabbar for a view, call as such : 'Dim v As New View1 'hideTabBar(v, Self) // @property(nonatomic) BOOL hidesBottomBarWhenPushed Declare Sub setHidesBottomBarWhenPushed Lib "UIKit.framework" _ Selector "setHidesBottomBarWhenPushed:" (id As Ptr, value As Boolean) setHidesBottomBarWhenPushed(childview.ViewControllerHandle, True) parentView.PushTo(childView) // To reinstate the tab bar, close the pushed view. End Sub
Sub SetTabBarBadgeXC(extends v As MobileScreen, ItemIndex As Integer, Badge As String) Declare Function tabbar_ Lib "UIKit.framework" selector "tabBar"(o As Ptr) As Ptr Declare Function items_ Lib "UIKit.framework" selector "items" (o As ptr) As ptr Declare Function objectAtIndex Lib "Foundation.framework" selector "objectAtIndex:" (theArray As Ptr, idx As Integer) As Ptr Dim tb As iOSTabBar = v.ParentTabBar If tb Is Nil Then Return Dim h As ptr = tb.ViewControllerHandle Dim tabbar As Ptr = tabbar_(h) Dim items As ptr = items_(tabbar) Dim item0 As ptr = objectAtIndex(items, ItemIndex) Declare Sub setBadgeValue Lib "UIKit.framework" selector "setBadgeValue:" (obj_id As ptr, value As CFStringRef) if Badge.IsEmpty then setBadgeValue(item0, nil) else setBadgeValue(item0, Badge) end if End Sub
Sub SetTabBarButtonColorXC(extends v as MobileScreen, buttonColor as color) Declare Function tabbar_ lib "UIKit.framework" selector "tabBar"(o as Ptr) as Ptr dim tb as iOSTabBar=v.ParentTabBar if tb is nil then Return dim h as ptr = tb.ViewControllerHandle dim tabbar as Ptr = tabbar_(h) declare sub setTintColor lib "UIKit.framework" selector "setTintColor:" (id as ptr, UIColor as Ptr) setTintColor tabBar, UIColorFromColor(buttonColor) End Sub
Sub SetTabBarColorXC(extends v as MobileScreen, barColor as color, translucent as boolean = false) Declare Function tabbar_ Lib "UIKit.framework" selector "tabBar"(o As Ptr) As Ptr dim tb as iOSTabBar=v.ParentTabBar if tb is nil then Return dim h as ptr = tb.ViewControllerHandle dim tabbar as Ptr = tabbar_(h) Declare Sub setBarTintColor Lib "UIKit.framework" selector "setBarTintColor:" (id As ptr, UIColor As Ptr) setBarTintColor tabBar, UIColorFromColor(barColor) if translucent then declare sub setTranslucent lib "UIKit.framework" selector "setTranslucent:" (id as ptr) setTranslucent tabbar end End Sub
Sub SetTabBarNotCustomisableXC(extends view As MobileScreen) Dim tb As iOSTabBar = view.ParentTabBar If tb <> Nil Then Dim h As ptr = tb.ViewControllerHandle Declare Sub setCustomizableViewControllers Lib "UIKit" selector "setCustomizableViewControllers:" (o As Ptr, v As Ptr) setCustomizableViewControllers(h, Nil) End If End Sub
Sub SetTabBarSelectedImageXC(extends v As MobileScreen, ItemIndex As Integer, Image As Picture) Declare Function tabbar_ Lib "UIKit.framework" selector "tabBar"(o As Ptr) As Ptr Declare Function items_ Lib "UIKit.framework" selector "items" (o As ptr) As ptr Declare Function objectAtIndex Lib "Foundation.framework" selector "objectAtIndex:" (theArray As Ptr, idx As Integer) As Ptr Dim tb As iOSTabBar = v.ParentTabBar If tb Is Nil Then Return Dim h As ptr = tb.ViewControllerHandle Dim tabbar As Ptr = tabbar_(h) Dim items As ptr = items_(tabbar) Dim item0 As ptr = objectAtIndex(items, ItemIndex) Declare Sub setSelectedImage Lib "UIKit.framework" selector "setSelectedImage:" (obj_id As ptr, value As ptr) if image is nil then setSelectedImage(item0, nil) else setSelectedImage(item0, Image.Handle) end if End Sub
Sub SetTabBarTitleXC(extends v As MobileScreen, value As String) Declare function tabBarItem lib "UIKit" selector "tabBarItem" (obj as ptr) as ptr Declare sub setTitle lib "UIKit" selector "setTitle:" (obj as ptr, value as cfstringref) Dim item As Ptr = tabBarItem(v.ViewControllerHandle) setTitle(item, value) End Sub
Sub SetTabBarUnselectedColorXC(extends v as MobileScreen, unselectedColor as color) Declare Function tabbar_ lib "UIKit.framework" selector "tabBar"(o as Ptr) as Ptr dim tb as iOSTabBar = v.ParentTabBar if tb is nil then Return dim h as ptr = tb.ViewControllerHandle dim tabbar as Ptr = tabbar_(h) declare sub setUnselectedItemTintColor lib "UIKit.framework" selector "setUnselectedItemTintColor:" (id as ptr, UIColor as Ptr) setUnselectedItemTintColor tabBar, UIColorFromColor(unselectedColor) End Sub
Protected Sub SetTabPageXC(idx as integer, doReset as Boolean = False) 'This method has been posted in the forum by Antonio Rinaldi. 'It allows setting the active tab like if the user had tapped himself on the tab icon, without need for PushTo. 'Index is zero based, left to right 'Sub goTabPage(idx as integer,doReset as Boolean=False) if idx<0 then Return Declare Function NSClassFromString lib "Foundation"(cls as CFStringRef) as Ptr Declare function sharedApplication_ lib "UIKit" selector "sharedApplication"(cls_ptr as Ptr) as Ptr dim shAppPtr as Ptr=sharedApplication_(NSClassFromString("UIApplication")) Declare function keyWindow_ lib "UIkit" selector "keyWindow"(app_ptr as Ptr) as Ptr dim keyWinPtr as Ptr=keyWindow_(shAppPtr) Declare Function rootWiewController_ lib "UIKit" selector "rootViewController"(winPtr as Ptr) as Ptr dim rootWiewControllerPtr as Ptr=rootWiewController_(keyWinPtr) Declare Function isMemberOfClass_ lib "foundation" selector "isMemberOfClass:"(oPtr as Ptr,cPtr as Ptr) as Boolean dim a as ptr a=NSClassFromString("UITabBarController") if isMemberOfClass_(rootWiewControllerPtr,NSClassFromString("UITabBarController")) then Declare sub setSelectedIndex lib "UIKIT" selector "setSelectedIndex:"(tbPtr as Ptr,page as UInteger) setSelectedIndex(rootWiewControllerPtr,idx) if doReset then Declare Function selectedViewController_ lib "UIKIT" selector "selectedViewController"(oPtr as ptr) as Ptr dim navPtr as Ptr=selectedViewController_(rootWiewControllerPtr) Declare Sub popToRoot lib "UIKIT" selector "popToRootViewControllerAnimated:"(oPtr as Ptr,animated as Boolean) popToRoot(navPtr,true) end if end if 'End Sub End Sub
Private Function UIColorFromColor(value as color) As ptr Soft Declare Function colorWithRGBA Lib "UIKit" Selector "colorWithRed:green:blue:alpha:" (UIColorClassRef As Ptr, red As CGFloat, green As CGFloat, blue As CGFloat, alpha As CGFloat) As Ptr Soft Declare Function NSClassFromString Lib "Foundation" (classname As CFStringRef) As Ptr static UIColorClassPtr As Ptr = NSClassFromString("UIColor") Dim c as color = value Dim red As CGFloat = c.red / 255 Dim green As CGFloat = c.Green / 255 Dim blue As CGFloat = c.Blue / 255 Dim alpha As CGFloat = 1.0 - c.Alpha / 255 Dim colorPtr As ptr = colorWithRGBA(UIColorClassPtr, red, green, blue, alpha) Return colorPtr End Function
End Module
Module ImageExtensionsXC
Protected Function BestRepresentationXC(image As Picture) As Picture if image is nil then Return nil if image.ImageCount = 0 then Return image Dim scale As Double = ExtensionsXC.MainScreenScaleXC Return image.BestRepresentation(image.Width, image.Height, scale) End Function
Protected Function ImageForRTLXC(image As Picture) As Picture if image is nil then Return nil Dim bestImage As Picture = BestRepresentationXC(image) //Creates an image that is automatically flipped for RTL languages Declare Function imageFlippedForRightToLeftLayoutDirection Lib "UIKit.framework" selector "imageFlippedForRightToLeftLayoutDirection" (id As ptr) As ptr Return Picture.FromHandle(imageFlippedForRightToLeftLayoutDirection(bestImage.Handle)) End Function
Protected Function ImageOriginalXC(image As Picture) As Picture if image is nil then Return nil Dim bestImage As Picture = BestRepresentationXC(image) //Creates an image that will draw using the current Fillcolor Const UIImageRenderingModeAlwaysOriginal = 1 Declare Function imageWithRenderingMode Lib "UIKit.framework" selector "imageWithRenderingMode:" (id As ptr, RenderingMode As Integer) As ptr 'Dim imgHandle As Ptr = image.CopyOSHandle(Picture.HandleType.iOSUIImage) If bestImage.Handle = nil and image.Type = Picture.Types.MutableBitmap then Return Picture.FromHandle(imageWithRenderingMode(image.CopyOSHandle(Picture.HandleType.iOSUIImage), UIImageRenderingModeAlwaysOriginal)) Elseif bestImage.Handle = nil and image.Type = Picture.types.Image then Return Picture.FromHandle(imageWithRenderingMode(bestimage.CopyOSHandle(Picture.HandleType.iOSUIImage), UIImageRenderingModeAlwaysOriginal)) Else 'Return Picture.FromHandle(imageWithRenderingMode(imgHandle, UIImageRenderingModeAlwaysOriginal)) Return Picture.FromHandle(imageWithRenderingMode(bestImage.Handle, UIImageRenderingModeAlwaysOriginal)) End If End Function
Protected Function ImageWithBrushXC(image as Picture, brush as GraphicsBrush) As Picture If image Is Nil Then Return Nil Dim bestImage As Picture = BestRepresentationXC(image) Dim scale As Double = bestImage.VerticalResolution/72 Dim b As New Picture(bestImage.Width, bestImage.Height) b.VerticalResolution = bestImage.VerticalResolution b.HorizontalResolution = bestImage.HorizontalResolution Dim g As Graphics = b.Graphics g.Scale(scale, scale) Dim tmp As Picture = imageWithMaskXC(bestImage) g.Brush = brush g.FillRectangle(0, 0, g.Width, g.Height) g.DrawingColor = &cFFFFFF 'g.DrawPicture(tmp, 0, 0, tmp.Width, tmp.Height) g.DrawPicture(tmp, 0, 0) Return b End Function
Protected Function ImageWithColorXC(image as Picture, value as Color) As Picture If image Is Nil Then Return Nil Dim bestImage As Picture = BestRepresentationXC(image) if ExtensionsXC.GetiOSVersionXC >= 13 then //Thanks to Yvonnick Maçon https://tracker.xojo.com/xojoinc/xojo/-/issues/71220#note_545958 'https://developer.apple.com/documentation/uikit/uiimage/3327300-imagewithtintcolor?language=objc declare function imageWithTintColor_ lib "UIKit" selector "imageWithTintColor:" ( img as ptr, tint as ptr ) as ptr dim newimage as ptr = imageWithTintColor_( bestImage.Handle, UIColorFromColor( value ) ) dim pp as Picture = Picture.FromHandle( newimage ) Return pp Else Const UIImageRenderingModeAlwaysOriginal = 1 Declare Function imageWithRenderingMode Lib "UIKit.framework" selector "imageWithRenderingMode:" (id As ptr, RenderingMode As Integer) As ptr Dim scale As Double = bestImage.VerticalResolution/72 Dim b As New Picture(bestImage.Width, bestImage.Height) b.VerticalResolution = bestImage.VerticalResolution b.HorizontalResolution = bestImage.HorizontalResolution Dim g As Graphics = b.Graphics g.Scale(scale, scale) Dim tmp As Picture = imageWithMaskXC(bestImage) g.DrawingColor = value g.DrawPicture(tmp, 0, 0) Return Picture.FromHandle(imageWithRenderingMode(b.CopyOSHandle(Picture.HandleTypes.iOSUIImage), UIImageRenderingModeAlwaysOriginal)) Return b end if End Function
Protected Function ImageWithMaskXC(image As Picture) As Picture if image is nil then Return nil Dim bestImage As Picture = BestRepresentationXC(image) //Creates an image that will draw using the current Fillcolor const UIImageRenderingModeAlwaysTemplate = 2 Declare Function imageWithRenderingMode lib "UIKit.framework" selector "imageWithRenderingMode:" (id as ptr, RenderingMode as Integer) as ptr 'Dim imgHandle As Ptr = image.CopyOSHandle(Picture.HandleType.iOSUIImage) 'Return Picture.FromHandle(imageWithRenderingMode(imgHandle, UIImageRenderingModeAlwaysTemplate)) Return Picture.FromHandle(imageWithRenderingMode(bestImage.Handle, UIImageRenderingModeAlwaysTemplate)) End Function
Protected Function ResizableTiledImageXC(CapInsets As ExtensionsXC.xcUIEdgeInsets, image As Picture) As Picture if image is nil then Return nil Declare Function resizableImageWithCapInsets Lib "UIKit.framework" selector "resizableImageWithCapInsets:" (id As ptr, insets As ExtensionsXC.xcUIEdgeInsets) As ptr Dim bestImage As Picture = BestRepresentationXC(image) Return Picture.FromHandle (resizableImageWithCapInsets(bestImage.handle, CapInsets)) End Function
Sub SaveToCameraRollXC(extends pic As Picture) 'Jason King 'Just saw this conversation - its entirely possible with declares. Just pop this short function into a module and call it like "img.SaveToCameraRoll" declare sub UIImageWriteToSavedPhotosAlbum lib "UIKit" (img as ptr, target as ptr, sel as ptr, info as ptr) UIImageWriteToSavedPhotosAlbum(pic.CopyOSHandle(picture.HandleTypes.iOSUIImage),nil,nil,nil) End Sub
Protected Function SystemImageXC(name As String, fallback As Picture = nil) As Picture if ExtensionsXC.GetiOSVersionXC >= 13.0 then Declare Function systemImageNamed lib "UIKit.framework" selector "systemImageNamed:" (cls as ptr, name as CFStringRef) as ptr declare function NSClassFromString lib "Foundation.framework" (clsName as CFStringRef) as ptr Dim imgRef As ptr = systemImageNamed(NSClassFromString("UIImage"), name) if imgRef <> nil then Return Picture.FromHandle(imgRef) Else Break //image doesn't exist Return fallback end if Else //iOS version prior to 13.0 Return fallback end if End Function
Function ToTemplateXC(extends image As Picture) As Picture if image is nil then Return nil Dim bestImage As Picture = BestRepresentationXC(image) //Creates an image that will draw using the current Fillcolor const UIImageRenderingModeAlwaysTemplate = 2 Declare Function imageWithRenderingMode lib "UIKit.framework" selector "imageWithRenderingMode:" (id as ptr, RenderingMode as Integer) as ptr 'Dim imgHandle As Ptr = image.CopyOSHandle(Picture.HandleType.iOSUIImage) #if DebugBuild if bestImage.Handle = nil then Break end if #endif 'Return Picture.FromHandle(imageWithRenderingMode(imgHandle, UIImageRenderingModeAlwaysTemplate)) Return Picture.FromHandle(imageWithRenderingMode(bestImage.Handle, UIImageRenderingModeAlwaysTemplate)) End Function
Private Function UIColorFromColor(value as color) As ptr Soft Declare Function colorWithRGBA Lib "UIKit" Selector "colorWithRed:green:blue:alpha:" (UIColorClassRef As Ptr, red As CGFloat, green As CGFloat, blue As CGFloat, alpha As CGFloat) As Ptr Soft Declare Function NSClassFromString Lib "Foundation" (classname As CFStringRef) As Ptr static UIColorClassPtr As Ptr = NSClassFromString("UIColor") Dim c as color = value Dim red As CGFloat = c.red / 255 Dim green As CGFloat = c.Green / 255 Dim blue As CGFloat = c.Blue / 255 Dim alpha As CGFloat = 1.0 - c.Alpha / 255 Dim colorPtr As ptr = colorWithRGBA(UIColorClassPtr, red, green, blue, alpha) Return colorPtr End Function
End Module
Module AppExtensionsXC
ComputedProperty Protected IdleTimerDisabled As Boolean
Sub Set() Declare Sub setIdleTimerDisabled Lib "UIKit" selector "setIdleTimerDisabled:" _ (app_id As ptr, value As Boolean) setIdleTimerDisabled(SharedApplication, value) End Set
Sub Get() Declare Function isIdleTimerDisabled Lib "UIKit" selector "isIdleTimerDisabled" _ (app_id As ptr) As Boolean return isIdleTimerDisabled(SharedApplication) End Get
End ComputedProperty
Enum UIStatusBarStyle default LightContent DarkContent End Enum
Sub OpeniOSSettingsXC(extends app As MobileApplication) #Pragma Unused app Declare Function NSClassFromString Lib "Foundation.framework" (clsName As CFStringRef) As ptr Declare Function URLWithString Lib "Foundation" Selector "URLWithString:" ( id As Ptr, URLString As CFStringRef ) As Ptr Dim openSettingsURL As ptr = ExtensionsXC.LoadConstantXC("UIKit", "UIApplicationOpenSettingsURLString") Declare Function stringWithString Lib "Foundation.framework" selector "stringWithString:" (clsRef As ptr, Str As ptr) As CFStringRef Dim nsURL As ptr = URLWithString(NSClassFromString("NSURL"), openSettingsURL.CFStringRef(0)) Declare Function sharedApplication Lib "UIKit" Selector "sharedApplication" (obj As Ptr) As Ptr Dim sharedApp As Ptr = sharedApplication(NSClassFromString("UIApplication")) If ExtensionsXC.GetiOSVersionXC >= 10.0 Then Declare Sub openURL Lib "UIKit" Selector "openURL:options:completionHandler:" (id As Ptr, nsurl As Ptr, options As ptr, completion As ptr) openURL(sharedApp, nsURL, nil, nil) Else Declare Function openURL Lib "UIKit" Selector "openURL:" (id As Ptr, nsurl As Ptr) As Boolean call openURL(sharedApp, nsURL) End If End Sub
Sub SetBrightnessXC(extends app as MobileApplication, value as Double) #Pragma unused app Declare Function NSClassFromString Lib "Foundation" (aClassName As CFStringRef) As Ptr Declare Function mainScreen Lib "UIKit" selector "mainScreen" (classRef As Ptr) As ptr Declare sub setBrightness Lib "UIKit" selector "setBrightness:" (obj As Ptr, value As CGFloat) Dim screenRef As ptr = mainScreen(NSClassFromString("UIScreen")) setBrightness(screenRef, value) End Sub
Sub SetStatusBarStyleXC(extends app As MobileApplication, style As AppExtensionsXC.UIStatusBarStyle) #Pragma Unused app Declare Function NSClassFromString Lib "Foundation" (className As CFStringRef) As Ptr Declare Function sharedApplication Lib "UIKit" Selector "sharedApplication" (obj As Ptr) As Ptr Declare sub setStatusBarStyle lib "UIKit" selector "setStatusBarStyle:" (obj as ptr, style as UIStatusBarStyle) Dim sharedApp As Ptr = sharedApplication(NSClassFromString("UIApplication")) setStatusBarStyle(sharedApp, style) End Sub
Sub SetStatusBarStyleXC1(extends app As MobileApplication, style As AppExtensionsXC.UIStatusBarStyle) #Pragma Unused app Declare Function NSClassFromString Lib "Foundation" (className As CFStringRef) As Ptr Declare Function sharedApplication Lib "UIKit" Selector "sharedApplication" (obj As Ptr) As Ptr Declare sub setStatusBarStyle lib "UIKit" selector "setStatusBarStyle:" (obj as ptr, style as UIStatusBarStyle) Dim sharedApp As Ptr = sharedApplication(NSClassFromString("UIApplication")) setStatusBarStyle(sharedApp, style) End Sub
Sub SetWindowColorXC(extends app as MobileApplication, value as color) #Pragma unused app Dim uic As UIKit.UIColor If value.Alpha = 255 Then uic = UIKit.UIColor.ClearColor Else uic = New UIKit.UIColor(value) End If Declare Function NSClassFromString Lib "UIKit.framework" (clsName As CFStringRef) As ptr Declare Function sharedApplication Lib "UIKit.framework" selector "sharedApplication" (clsRef As ptr) As ptr Declare Function keyWindow Lib "UIKit.framework" selector "keyWindow" (obj_id As ptr) As ptr Dim myWindowPtr As ptr = keyWindow(sharedApplication(NSClassFromString("UIApplication"))) If myWindowPtr = Nil Then Break //this needs to be called from the Activate event, not the Open event Return End If Declare Sub setBackgroundColor Lib "UIKit.framework" selector "setBackgroundColor:" (obj_id As ptr, col As ptr) setBackgroundColor(myWindowPtr, uic) End Sub
Protected Function SharedApplication() As Ptr Declare Function NSClassFromString Lib "Foundation" (className As CFStringRef) As Ptr declare function sharedApplication lib "UIKit" selector "sharedApplication" (clsRef as ptr) as ptr Return sharedApplication(NSClassFromString("UIApplication")) End Function
End Module
Module TableSearchExtensionsXC
Function GetSearchFilterIndexXC(extends table as iOSMobileTable) As Integer // Get the searchbar from the search controller Declare Function searchBar Lib "UIKit" selector "searchBar" (obj As ptr) As ptr Var searchPtr As ptr = table.SearchControllerHandle Var searchBarObj As ptr = searchBar(searchPtr) // Ask the searchbar for the index of the selected scope Declare Function selectedScopeButtonIndex Lib "UIKit" selector "selectedScopeButtonIndex" (obj As ptr) As Integer Return selectedScopeButtonIndex(searchBarObj) End Function
Sub SetSearchActiveXC(extends table As iOSMobileTable, value As Boolean) // Put them on the searchbar Declare Function searchBar Lib "UIKit" selector "searchBar" (obj As ptr) As ptr Var searchPtr As ptr = table.SearchControllerHandle Declare sub setActive lib "UIKit" selector "setActive:" (obj as ptr, value as Boolean) setActive(searchPtr, value) End Sub
Sub SetSearchFieldTextColorXC(extends table As iOSMobileTable, value As Color) if ExtensionsXC.GetiOSVersionXC >= 13.0 then // Get the searchBar object Declare Function searchBar Lib "UIKit" selector "searchBar" (obj As ptr) As ptr Declare Function searchTextField Lib "UIKit" selector "searchTextField" (obj As ptr) As ptr Var searchPtr As ptr = table.SearchControllerHandle Var searchBarObj As ptr = searchBar(searchPtr) Var textFieldObj As ptr = searchTextField(searchBarObj) //Now do something Dim uic As UIKit.UIColor If value.Alpha = 255 Then uic = UIKit.UIColor.ClearColor Else uic = New UIColor(value) End If Declare Sub setTextColor_ Lib "UIKit.framework" selector "setTextColor:" (obj_id As ptr, col As ptr) setTextColor_(textFieldObj, uic) end if End Sub
Sub SetSearchFiltersXC(extends table as iOSMobileTable, assigns value() as string) // Convert the string array into an NSMutableArray Declare Function NSClassFromString Lib "Foundation" (aString As CFStringRef) As Ptr Declare Function arrayWithCapacity Lib "Foundation" selector "arrayWithCapacity:" (cls As ptr, count as UInteger) As ptr Declare Sub addObject Lib "Foundation" selector "addObject:" (arr As ptr, obj As CFStringRef) Dim nsarray As ptr = arrayWithCapacity(NSClassFromString("NSMutableArray"), value.LastIndex+1) For i As Integer = 0 To value.LastIndex addObject(nsarray, value(i)) Next // Put them on the searchbar Declare Function searchBar Lib "UIKit" selector "searchBar" (obj As ptr) As ptr Var searchPtr As ptr = table.SearchControllerHandle Var searchBarObj As ptr = searchBar(searchPtr) Declare Sub setScopeButtonTitles Lib "UIKit" selector "setScopeButtonTitles:" (obj As ptr, arr As ptr) setScopeButtonTitles(searchBarObj, nsarray) // Enable it if the count > 0 Declare Sub setShowsScopeBar Lib "UIKit" selector "setShowsScopeBar:" (obj As ptr, value As Boolean) setShowsScopeBar(searchBarObj, value.LastIndex>-1) End Sub
Sub SetSearchPlaceholderXC(extends table As iOSMobileTable, value As String) If ExtensionsXC.GetiOSVersionXC >= 13.0 then // Get the searchBar object Declare Function searchBar Lib "UIKit" selector "searchBar" (obj As ptr) As ptr Var searchPtr As ptr = table.SearchControllerHandle Var searchBarObj As ptr = searchBar(searchPtr) Declare sub setPlaceholder lib "UIKit" selector "setPlaceholder:" (obj as ptr, value as CFStringRef) setPlaceholder(searchBarObj, value) End If End Sub
End Module
Module SliderExtensionsXC
Sub SetMaximumTrackTintColorXC(extends slider as MobileSlider, value as Color) Dim uic As UIKit.UIColor If value.Alpha = 255 Then uic = UIKit.UIColor.ClearColor Else uic = New UIColor(value) End If declare sub maximumTrackTintColor_ lib "UIKit.framework" selector "setMaximumTrackTintColor:" (id as ptr, UIColor as Ptr) maximumTrackTintColor_(slider.Handle, uic) End Sub
Sub SetMaximumValueImageXC(extends slider as MobileSlider, value as Picture) Declare sub SetMaximumValueImage_ lib "UIKit" Selector "setMaximumValueImage:" (obj as ptr, value as ptr) SetMaximumValueImage_(slider.Handle, value.CopyOSHandle(Picture.HandleType.iOSUIImage)) End Sub
Sub SetMinimumTrackTintColorXC(extends slider as MobileSlider, value as Color) Dim uic As UIKit.UIColor If value.Alpha = 255 Then uic = UIKit.UIColor.ClearColor Else uic = New UIColor(value) End If declare sub minimumTrackTintColor_ lib "UIKit.framework" selector "setMinimumTrackTintColor:" (id as ptr, UIColor as Ptr) minimumTrackTintColor_(slider.Handle, uic) End Sub
Sub SetMinimumValueImageXC(extends slider as MobileSlider, value as Picture) Declare sub SetMinimumValueImage_ lib "UIKit" Selector "setMinimumValueImage:" (obj as ptr, value as ptr) SetMinimumValueImage_(slider.Handle, value.CopyOSHandle(Picture.HandleType.iOSUIImage)) End Sub
Sub SetThumbTintColorXC(extends slider As MobileSlider, value As Color) Dim uic As UIKit.UIColor If value.Alpha = 255 Then uic = UIKit.UIColor.ClearColor Else uic = New UIColor(value) End If declare sub thumbTintColor_ lib "UIKit.framework" selector "setThumbTintColor:" (id as ptr, UIColor as Ptr) thumbTintColor_(slider.Handle, uic) End Sub
End Module
Module AccessibilityExtensionsXC
Sub AccessibilityLabelXC(extends tb As MobileToolbarButton, assigns value As String) tb.SetAccessibilityLabelXC(value) End Sub
Sub AccessibilityLabelXC(extends control As MobileUIControl, assigns value As String) Declare sub setAccessibilityLabel lib "Foundation.framework" selector "setAccessibilityLabel:" (obj as ptr, value as CFStringRef) setAccessibilityLabel(control.Handle, value) End Sub
Sub MakeAccessibleXC(extends control As MobileUIControl, value As Boolean) Declare sub isAccessibilityElement lib "Foundation" selector "setIsAccessibilityElement:" (obj as ptr, value as boolean) isAccessibilityElement(control.Handle, value) End Sub
Sub PostAnnouncementNotificationXC(value As String) 'declare sub UIAccessibilityPostNotification lib "UIKit" Selector "UIAccessibilityPostNotification" (obj as ptr, notification as ptr, value as ptr) if isVoiceOverRunningXC then Declare sub UIAccessibilityPostNotification lib "UIKit" alias "UIAccessibilityPostNotification" (notification as ptr, value as CFStringRef) Dim type As ptr = ExtensionsXC.LoadConstantXC("UIKit", "UIAccessibilityAnnouncementNotification") 'Dim s As new NSString(value) UIAccessibilityPostNotification(type, value) end if End Sub
Sub SetAccessibilityLabelXC(extends tb As MobileToolbarButton, value As String) Declare sub setAccessibilityLabel lib "Foundation.framework" selector "setAccessibilityLabel:" (obj as ptr, value as CFStringRef) setAccessibilityLabel(tb.Handle, value) End Sub
Protected Function isVoiceOverRunningXC() As Boolean Declare function isVoiceOverRunning lib "UIKit" alias "UIAccessibilityIsVoiceOverRunning" as Boolean Return isVoiceOverRunning End Function
End Module
Module SplitViewExtensionsXC
Enum UISplitViewControllerBackgroundStyle None Sidebar = 1 End Enum
Enum UISplitViewControllerDisplayMode Automatic = 0 secondaryOnly oneBesideSecondary oneOverSecondary End Enum
Function IsCollapsedXC(Extends scr As iOSSplitView) As Boolean //Changes the SplitView in portrait mode Declare function isCollapsed Lib "UIKit" _ selector "setPreferredDisplayMode:" (obj As Ptr) as Boolean Return isCollapsed(scr.ViewControllerHandle) End Function
Sub SetDisplayModeXC(Extends scr As iOSSplitView, mode As SplitViewExtensionsXC.UISplitViewControllerDisplayMode) //Changes the SplitView in portrait mode Declare Sub setPreferredDisplayMode Lib "UIKit" _ selector "setPreferredDisplayMode:" (obj As Ptr, mode As UISplitViewControllerDisplayMode) setPreferredDisplayMode(scr.ViewControllerHandle, mode) End Sub
Sub SetMaximumPrimaryColumnWidthXC(Extends scr as iOSSplitView, width as Double) Declare Sub setMaximumPrimaryColumnWidth Lib "UIKit" _ selector "setMaximumPrimaryColumnWidth:" (obj As Ptr, width as Double) setMaximumPrimaryColumnWidth(scr.ViewControllerHandle, width) End Sub
Sub SetMinimumPrimaryColumnWidthXC(Extends scr as iOSSplitView, width as Double) Declare Sub setMinimumPrimaryColumnWidth Lib "UIKit" _ selector "setMinimumPrimaryColumnWidth:" (obj As Ptr, width as Double) setMinimumPrimaryColumnWidth(scr.ViewControllerHandle, width) End Sub
Sub SetPreferredPrimaryColumnWidthFractionXC(Extends scr as iOSSplitView, fraction as Double) Declare Sub setPreferredPrimaryColumnWidthFraction Lib "UIKit" _ selector "setPreferredPrimaryColumnWidthFraction:" (obj As Ptr, fraction as CGFloat) setPreferredPrimaryColumnWidthFraction(scr.ViewControllerHandle, fraction) End Sub
Sub SetPrimaryBackgroundStyleXC(Extends scr as iOSSplitView, style as SplitViewExtensionsXC.UISplitViewControllerBackgroundStyle) //More info: https://developer.apple.com/documentation/uikit/uisplitviewcontroller/3238075-primarybackgroundstyle?language=objc // In macOS, the sidebar of a split view shows a blurred desktop behind its view. // To achieve this effect in your iPad app when it runs in macOS, // set primaryBackgroundStyle to UISplitViewControllerBackgroundStyleSidebar. // Set the style to UISplitViewControllerBackgroundStyleNone when you want to control the background appearance of the primary view controller. Declare sub setPrimaryBackgroundStyle lib "UIKit" _ selector "setPrimaryBackgroundStyle:" (obj As Ptr, style As UISplitViewControllerBackgroundStyle) setPrimaryBackgroundStyle(scr.ViewControllerHandle, style) End Sub
End Module
Module MapViewerExtensionsXC
Const MapKitLib = "MapKit"
Enum MKMapType standard = 0 satellite hybrid satelliteFlyover hybridFlyover mutedStandard End Enum
Sub AddPolyLineXC(extends map as MobileMapViewer, coordinates() as Pair) declare function NSClassFromString lib "Foundation" (clsName as cfstringref) as ptr declare function polylineWithCoordinates lib MapKitLib selector "polylineWithCoordinates:count:" (obj as ptr, coord as ptr, cnt as UInteger) as ptr declare sub addOverlay lib MapKitLib selector "addOverlay:" (obj as ptr, overlay as ptr) 'declare function malloc lib "/usr/lib/libobjc.A.dylib" (size as UInteger) as ptr Var mb As New MemoryBlock(0) Var bs As New BinaryStream(mb) For each c as pair in coordinates bs.WriteDouble(c.Left.DoubleValue) bs.WriteDouble(c.Right.DoubleValue) Next c bs.Close Dim mbPtr As Ptr = mb.Ptr(0) dim polyline As Ptr = polylineWithCoordinates(NSClassFromString("MKPolyline"), mb, coordinates.Count) addOverlay(map.Handle, polyline) End Sub
Sub SetMapTypeXC(extends map As MobileMapViewer, value As MapViewerExtensionsXC.MKMapType) Declare sub setMapType lib MapKitLib selector "setMapType:" (obj as ptr, value as MKMapType) setMapType(map.Handle, value) End Sub
End Module
End Project

See also:

Download this example: Subscription with MBS.zip

The items on this page are in the following plugins: MBS MacCloud Plugin.


The biggest plugin in space...