CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-jetbrains-compose-ui--ui-util-uikitsimarm64

iOS UIKit simulator ARM64 utilities for Compose Multiplatform UI framework providing testing, interoperability, and platform-specific implementations.

Pending
Overview
Eval results
Files

coordinate-utilities.mddocs/

Coordinate Utilities

Conversion utilities between Compose coordinate systems and iOS Core Graphics coordinates, providing seamless interoperability for layout calculations, touch event handling, and UI positioning.

Capabilities

Core Graphics Conversion

Functions for converting between Compose coordinates and iOS Core Graphics coordinate system.

/**
 * Converts Compose DpOffset to Core Graphics CGPoint
 * @return CValue<CGPoint> representing the same position in Core Graphics coordinates
 */
internal fun DpOffset.toCGPoint(): CValue<CGPoint>

/**
 * Converts Core Graphics CGPoint to Compose DpOffset
 * @return DpOffset representing the same position in Compose coordinates
 */
internal fun CValue<CGPoint>.toDpOffset(): DpOffset

Usage Examples:

// Convert Compose coordinates to Core Graphics for UIKit integration
val composeOffset = DpOffset(100.dp, 150.dp)
val cgPoint = composeOffset.toCGPoint()

// Convert Core Graphics coordinates back to Compose
val backToCompose = cgPoint.toDpOffset()
assert(backToCompose == composeOffset)

Rectangle Conversion

Functions for converting between different rectangle coordinate systems with density conversion support.

/**
 * Converts DpRect to pixel Rect using provided density
 * @param density - Screen density for dp-to-pixel conversion
 * @return Rect in pixel coordinates
 */
internal fun DpRect.toRect(density: Density): Rect

/**
 * Converts pixel Rect to DpRect using provided density
 * @param density - Screen density for pixel-to-dp conversion  
 * @return DpRect in density-independent coordinates
 */
internal fun Rect.toDpRect(density: Density): DpRect

/**
 * Converts Core Graphics CGRect to Compose DpRect
 * @return DpRect representing the same rectangle in Compose coordinates
 */
internal fun CValue<CGRect>.toDpRect(): DpRect

Usage Examples:

runUIKitInstrumentedTest {
    val dpRect = DpRect(
        offset = DpOffset(10.dp, 20.dp),
        size = DpSize(100.dp, 50.dp)
    )
    
    // Convert to pixel coordinates for UIKit operations
    val pixelRect = dpRect.toRect(density)
    
    // Convert back to dp coordinates
    val backToDp = pixelRect.toDpRect(density)
}

Rectangle Geometry Operations

Utility functions for rectangle geometry calculations and spatial relationships.

/**
 * Calculates the center point of the rectangle
 * @return DpOffset representing the center coordinates
 */
val DpRect.center: DpOffset

/**
 * Creates a zero-size DpRect at origin
 * @return DpRect with zero width and height at (0, 0)
 */
fun DpRectZero(): DpRect

/**
 * Calculates intersection of two rectangles
 * @param other - Rectangle to intersect with
 * @return DpRect representing intersection area, or null if no intersection
 */
fun DpRect.intersect(other: DpRect): DpRect?

Usage Examples:

val rect1 = DpRect(
    offset = DpOffset(0.dp, 0.dp),
    size = DpSize(100.dp, 100.dp)
)

val rect2 = DpRect(
    offset = DpOffset(50.dp, 50.dp),
    size = DpSize(100.dp, 100.dp)
)

// Get center of rectangle
val center = rect1.center // DpOffset(50.dp, 50.dp)

// Calculate intersection
val intersection = rect1.intersect(rect2)
// Result: DpRect(offset=DpOffset(50.dp, 50.dp), size=DpSize(50.dp, 50.dp))

// Create zero rectangle
val zeroRect = DpRectZero() // DpRect(offset=DpOffset.Zero, size=DpSize.Zero)

View Coordinate Utilities

Functions for working with UIView coordinate systems and screen-relative positioning.

/**
 * Gets view bounds in window coordinates as DpRect
 * @return DpRect representing view bounds in window coordinate system
 */
fun UIView.dpRectInWindow(): DpRect

Usage Example:

// Get UIView bounds in window coordinates
val viewBounds = someUIView.dpRectInWindow()
println("View is positioned at: ${viewBounds.offset}")
println("View size: ${viewBounds.size}")

// Use bounds for touch event targeting
val centerOfView = viewBounds.center
tap(centerOfView)

Coordinate System Integration

Compose to UIKit Coordinate Mapping

// Example: Converting Compose layout bounds to UIKit frame
runUIKitInstrumentedTest {
    setContent {
        Box(
            modifier = Modifier
                .offset(50.dp, 100.dp)
                .size(200.dp, 150.dp)
        ) {
            Text("Content")
        }
    }
    
    // Calculate equivalent UIKit frame
    val composeRect = DpRect(
        offset = DpOffset(50.dp, 100.dp),
        size = DpSize(200.dp, 150.dp)
    )
    
    val uikitFrame = composeRect.toRect(density)
    // Use uikitFrame for UIKit view positioning
}

Touch Event Coordinate Conversion

// Example: Converting touch events between coordinate systems
fun handleTouchEvent(cgPoint: CValue<CGPoint>) {
    val composeOffset = cgPoint.toDpOffset()
    
    // Process touch in Compose coordinate system
    processComposeTouch(composeOffset)
    
    // Convert back for UIKit if needed
    val backToCG = composeOffset.toCGPoint()
}

Layout Bounds Calculation

// Example: Complex layout bounds calculation
fun calculateLayoutBounds(views: List<UIView>): DpRect {
    val bounds = views.map { it.dpRectInWindow() }
    
    if (bounds.isEmpty()) return DpRectZero()
    
    val minX = bounds.minOf { it.left }
    val minY = bounds.minOf { it.top }
    val maxX = bounds.maxOf { it.right }
    val maxY = bounds.maxOf { it.bottom }
    
    return DpRect(
        offset = DpOffset(minX, minY),
        size = DpSize(maxX - minX, maxY - minY)
    )
}

Type Definitions

// Compose coordinate types
typealias DpOffset = androidx.compose.ui.unit.DpOffset
typealias DpRect = androidx.compose.ui.geometry.DpRect  
typealias DpSize = androidx.compose.ui.unit.DpSize
typealias Density = androidx.compose.ui.unit.Density

// Pixel coordinate types
typealias Rect = androidx.compose.ui.geometry.Rect
typealias Offset = androidx.compose.ui.geometry.Offset
typealias Size = androidx.compose.ui.geometry.Size

// iOS Core Graphics types (via Kotlin/Native)
// CValue<CGPoint> - Core Graphics point
// CValue<CGRect> - Core Graphics rectangle
// CValue<CGSize> - Core Graphics size

Platform-Specific Considerations

iOS Coordinate System Differences

  • Origin: iOS has origin at top-left, same as Compose
  • Y-Axis Direction: Both systems have Y increasing downward
  • Density Independence: Compose uses dp units, iOS uses points (similar concept)
  • Precision: Core Graphics uses CGFloat (Double on 64-bit), Compose uses Float for dp values

Performance Considerations

  • Conversion Overhead: Coordinate conversions are lightweight but should be cached for frequently accessed values
  • Density Lookup: Screen density is cached within test environment for optimal performance
  • Batch Operations: Group multiple coordinate conversions when possible for better performance

Thread Safety

  • Main Thread: All UIKit coordinate operations must occur on the main thread
  • Compose Thread: Coordinate calculations can be performed on any thread
  • Conversion Safety: Coordinate conversion functions are thread-safe and immutable

Install with Tessl CLI

npx tessl i tessl/maven-org-jetbrains-compose-ui--ui-util-uikitsimarm64

docs

accessibility-testing.md

coordinate-utilities.md

index.md

ios-uikit-testing.md

touch-simulation.md

tile.json