Cannot use instance member within property initializer
So if we decode the error message you can figure out whats wrong. It says property initializers run before self is available
so we need to adjust what we're doing since our property depends on bounds which belongs to self. Lets try a lazy variable. You can't use bounds in a let because it doesn't exist when that property is created because it belongs to self. So at init self isn't complete yet. But if you use a lazy var, then self and its property bounds will be ready by the time you need it.
lazy var arrowPath = UIBezierPath.bezierPathWithArrowFromPoint(startPoint: CGPoint(x: self.bounds.size.width/2,y: self.bounds.size.height/3), endPoint: CGPoint(x: self.bounds.size.width/2, y: self.bounds.size.height/3*2), tailWidth: 8, headWidth: 24, headLength: 18)
Cannot use instance member 'service' within property initializer; property initializers run before 'self' is available
Basically, what the compiler is saying is that "I'm still creating the instance of your DetailCardView
, I don't know yet what is the value of service
so I can't use it in the region
".
The solution is to pass the service
to a constant that will be used to initialise both properties. You need to create an initializer for your View where you pass this constant.
Here's how it looks:
let service: gService
// Rather than service.longitude and service.latitude, use a dummy value, like 0.0
// Recommended this var to be private
@State private var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 0.0, longitude: 0.0), span: MKCoordinateSpan(latitudeDelta: 0.0033, longitudeDelta: 0.0033))
// Here's your initializer
init(service: gService) {
self.service = service // Use service to initialise self.service
// Use service - and NOT self.service - to initialise region
region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: service.latitude, longitude: service.longitude), span: MKCoordinateSpan(latitudeDelta: 0.0033, longitudeDelta: 0.0033))
}
var body: some View {
... // The rest of your code
Another method you can try is to drop the init()
and set the region
when the view appears, like this:
let service: gService
// Rather than service.longitude and service.latitude, use a dummy value, like 0.0
// Recommended this var to be private
@State private var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 0.0, longitude: 0.0), span: MKCoordinateSpan(latitudeDelta: 0.0033, longitudeDelta: 0.0033))
var body: some View {
Map(coordinateRegion: $region, annotationItems: [MapPoint(coordinates: CLLocationCoordinate2D(latitude: service.latitude, longitude: service.longitude))]) { location in
MapAnnotation(coordinate: location.coordinates) {
Circle()
.stroke(.red, lineWidth: 3)
.frame(width: 50, height: 50, alignment: .center)
}
.onAppear {
region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: service.latitude, longitude: service.longitude), span: MKCoordinateSpan(latitudeDelta: 0.0033, longitudeDelta: 0.0033))
}
}
Cannot use instance member within property initializer; property initializers run before 'self' is available
If you want to use one class property (or in this case two) to initialize another class property, you need a way to make sure the required properties have already been set.
If you mark dateManager
as lazy
it won't be initialized until it's accessed for the first time. By the time it can be accessed, self
will be fully available so the compiler should be happy.
lazy var dateManager = DateManager(years: datePicker, time: timePicker)
Xcode error: Cannot use instance member 'selectedWateredDate' within property initializer; property initializers run before 'self' is available
Change the let property to a computed variable.
var dateInterval : DateInterval { DateInterval(start: selectedWateredDate, end: waterMeAgainIn)}
Cannot use instance member 'videoName' within property initializer; property initializers run before 'self' is available
Option 1:
Create an initializer for your View
that creates your @State
initial value:
struct ExercisingSessionView: View {
let exerciseName: String
let videoName: String
@State var player : AVPlayer
@State var isplaying = false
@State var showcontrols = false
init(exerciseName: String, videoName: String) {
self.exerciseName = exerciseName
self.videoName = videoName
self._player = State(initialValue: AVPlayer(url: URL(fileURLWithPath: Bundle.main.path(forResource: videoName, ofType: "mov")!)))
}
var body: some View {
CustomVideoPlayer(player: $player)
.frame(width: 390, height: 219)
.onTapGesture {
self.showcontrols = true
}
}
}
The downside to this is if ExercisingSessionView
gets initialized often (even if it doesn't get actually re-rendered to the view hierarchy), you're doing heavy lifting inside init
, which is generally a pretty bad idea for performance.
Option 2:
Declare player
as optional and load the initial value in onAppear
:
struct ExercisingSessionView: View {
let exerciseName: String
let videoName: String
@State var player : AVPlayer?
@State var isplaying = false
@State var showcontrols = false
var body: some View {
Group {
if let player = player {
CustomVideoPlayer(player: player)
.frame(width: 390, height: 219)
.onTapGesture {
self.showcontrols = true
}
}
}.onAppear {
player = AVPlayer(url: URL(fileURLWithPath: Bundle.main.path(forResource: videoName, ofType: "mov")!))
}
}
}
struct CustomVideoPlayer : UIViewControllerRepresentable {
var player: AVPlayer
func makeUIViewController(context: UIViewControllerRepresentableContext<CustomVideoPlayer>) -> AVPlayerViewController {
let controller = AVPlayerViewController()
controller.player = player
controller.showsPlaybackControls = false
return controller
}
func updateUIViewController(_ uiViewController: AVPlayerViewController, context: UIViewControllerRepresentableContext<CustomVideoPlayer>) {
}
}
This avoids the issue in option 1 because onAppear
will only be called once.
Note that here, I've made player
inside CustomVideoPlayer
a regular, non-binding property -- because AVPlayer
is an class, passed by reference, there's no reason to have a @Binding
with it.
SwiftUI Maps - Cannot use instance member within property initializer; property initializers run before 'self' is available
I was close in the final edit, but I needed to assign the value _region
- not the prefixed underscore. It looks like this is a private setter which is why you need to wrap the value in State
. And not forget to use the $
prefix to use the instance variable in the view.
struct PlaceDetail: View {
let place: Place
@State var region: MKCoordinateRegion
init(place: Place) {
self.place = place
let region = MKCoordinateRegion(
center: CLLocationCoordinate2D(latitude: place.latitude, longitude: place.longitude),
latitudinalMeters: 750,
longitudinalMeters: 750
)
self._region = State(initialValue: region)
}
var body: some View {
Map(coordinateRegion: $region)
}
}
Cannot use instance member 'generateRandomNumbers' within property initializer; property initializers run before 'self' is available
You are asking var array
to receive a "default" value from the function generateRandomNumbers()
. The "default" value is set during the initialisation of the instance of your view controller, so before the instance exists, so before the generateRandomNumbers()
function exists. The compiler doesn't know how to give a value to array
before the instance has finished being created.
A workaround is to set a dummy default value, then change it during initialisation, like this:
@IBOutlet weak var tableView1: UITableView!
var array = [Int]() // This is an empty array, the compiler can create it before the generateRandomNumbers() is available
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
tableView1.delegate = self
tableView1.dataSource = self
...
array = generateRandomNumbers(size: 1000) // Now that all variables are initialised, you can change their values
Related Topics
Uicollectionview - Diddeselectitematindexpath Not Called If Cell Is Selected
How to Get Only Images in the Camera Roll Using Photos Framework
Raw Image Data from Camera Like "645 Pro"
How to Disable Control Center in iOS 7 Programmatically and If Not, What Are Alternatives
How Does Xcode Find Implicit Target Dependencies
Decimal to Fraction Conversion in Swift
Could Not Load the "" Image Referenced from a Nib in the Bundle with Identifier
Custom Interactive Transition Animation
How to Detect the Orientation of the Device on iOS
Expand Uilabel Inside Uitableview with "More" Button Like Instagram
Launchscreen.Xib Not Displaying My Custom Font
Swiftui Hide Tabview Bar Inside Navigationlink Views