iOSControl BackgroundImage in XojoiOSWrapper

I am trying to modify code from Jim McKay that sets a button’s background image to do the same with an iOSContainerControl.

Now, I am not sure I found the right page in Apple’s Developer Library
https://developer.apple.com/reference/watchkit/wkinterfacegroup/1619663-setbackgroundimage

It is supposed to set the background image for a group container. Is iOSContainerControl a group container or something else ?

Public Sub BackdropCC(extends iOSCC As iOSContainerControl, assigns backdrop as iOSImage) declare sub setBackgroundImage lib "UIKit" selector "setBackgroundImage:" (obj as ptr, value as ptr) setBackgroundImage(iOSCC.Handle,backdrop.Handle) End Sub

I get this in the simulator console :
Apr 29 18:40:43 Michels-iMac My iOS App.debug[32623]: -[XOJContainerControl setBackgroundImage:]: unrecognized selector sent to instance 0xdf15e60
Apr 29 18:40:43 Michels-iMac My iOS App.debug[32623]: *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘-[XOJContainerControl setBackgroundImage:]: unrecognized selector sent to instance 0xdf15e60’

I am starting to suspect I did not find the adequate method. What is the underlying framework control of iOSContainerControl ?

BTW setBackgroundColor works just fine on an iOSContainerControl, just like on any other control.

An UIView does not own a backgroundImage property, right.
You have different options to choose from:

Either, as you proposed, address the CALayer behind it and use its contents property to add a CGImage. That’s not that many declares, so you could get around without a library.

Or create an UIColor(!) from the image and assign it to the View’s backgroundColor property. Colors created that way will tile the image, so this could get tricky if your layout orientation can be changed.

Or use an UIImageView and add it as a subview to the view. Of course, AppleLib will make that things a bit easier to use, but I could assist you in finding the right declares if you want to go without.

P.S.: I guess a ContainerControl is just an UIView. The declare you found is valid for a WKInterfaceGroup introduced with iOS 8.2, mainly for WatchKit.

If I understand right, this is indeed very close to what you described at https://forum.xojo.com/25274-buttons-seem-to-be-bound-to-background-image-and-disabled

[quote=209852:@Ulrich Bogun]If you want to try it with the color, and let’s say your Xojo view is called view1, try this in the open event of the view:

dim BGColor as new AppleColor (BGImage) // If you have an image BGImage in your project View1.AppleView.BackgroundColor = BGColor
If you go for the CALayer:

dim AppleBGImage as new appleImage (BGImage) View1.AppleView.Layer.Contents = AppleBGImage

Or 3rd way with an imageview:

ImageView1.AppleView.ExclusiveTouch = False [/quote]

How would I implement that with declares ? Say, the UIColor method which seems simpler ?

You know more about my posts than I do :wink:
But that’s basically the three methods known to me how to add an image to an UIView.

The declare (assuming you already have the NSClassFromString declare which you do):

Declare Function colorWithPatternImage lib "UIKit" selector "colorWithPatternImage:" (colorClass As Ptr, image as ptr) As Ptr Dim PatternColor As Ptr = colorWithPatternImage (NSClassFromString("UIColor"), myiOSImage.handle)

And then simply use the setBackgroundColor method with it on the handle of the ContainerControl.

Ulrich, you are the best !

I mixed my existing setBackgroundColor in the wrapper with what you just gave me, and IT WORKED RIGHT AWAY (Yeah!) :slight_smile: :slight_smile: :slight_smile:

[code]Public Sub BackdropCC(extends UIView as iOSContainerControl, assigns Img as iOSImage)
Declare Function NSClassFromString Lib “Foundation” (className As CFStringRef) As Ptr
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
Declare Function view Lib “UIKit” Selector “view” (UIViewController As Ptr) As Ptr
Declare Sub setBackgroundColor Lib “UIKit” Selector “setBackgroundColor:” (UIView As Ptr, UIColor As Ptr)

Declare Function colorWithPatternImage lib “UIKit” selector “colorWithPatternImage:” (colorClass As Ptr, image as ptr) As Ptr
Dim PatternColor As Ptr = colorWithPatternImage (NSClassFromString(“UIColor”), Img.handle)
Dim viewPtr As Ptr = UIView.Handle
setBackgroundColor(viewPtr, PatternColor)
End Sub
[/code]

I have added that to XojoiOSWrapper.

I just changed the title of this thread, because I have found that the same code can apply to several other iOSControls, such as iOSButtons, iOSTextArea, iOSTable…

Syntax is

iOSTable1.BacgroundImage = myImage

Download at https://github.com/Mitchboo/XojoiOSWrapper

For buttons I would recommend using setImageForState

Great. Any declare to share ?

Right now this is what I use in the wrapper :

[code]Public Sub Backdrop(extends b As iOSButton, assigns backdrop as iOSImage)
'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)
setBackgroundImage(b.Handle,backdrop.Handle,0)

//For use : iOSButton.Backdrop = Pic

End Sub
[/code]

So you got the declare already. The state which you pass to the declare is an UInteger bitmap, not a normal enumeration.
0 in that case means default state,
Bit 0 set = Highlighted,
Bit 1 set = disabled,
Bit 2 set = selected,
Bit 3 set = focused.

You can even define application-specific bits: Bit 4 and 5.
By default, highlighted and disabled images are drawn lighter resp. darker. You can change that behavior by the adjustsImageWhenHighlighted and adjustsImageWhenDisabled boolean properties:

Getter:

Declare function adjustsImageWhenHighlighted lib "UIKIt" selector "adjustsImageWhenHighlighted" (id as ptr) as boolean
Setter:

Declare sub setadjustsImageWhenHighlighted lib "UIKit" selector "setAdjustsImageWhenHighlighted:" (id as ptr, value as Boolean)

(and resp. for disabled state, id being the handle of the button.)

Thank you Ulrich.