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.