Finished reading: Golden Son by Pierce Brown đ
Finished reading: Golden Son by Pierce Brown đ
Finished reading: The Body by Bill Bryson đ
This is the final post in a series of reflections I am writing on the ideas of How to Calm Your Mind by Chris Bailey.
Iâve seen the rise of the term âDopamine Detoxâ on a certain subset of the internet over the past year. The idea is that the neurochemical dopamine is addicting people, especially young men, to a set of bad things: TikTok, unhealthy foods, porn, video games, etc. Like all viral ideas, there is a hint of truth in this but as the idea spreads online, it gets simplified and meme-ified to the point of becoming nonsensical scientifically.
This is why the How to Calm Your Mind chapter on âSimulation Fastingâ appealed to me.
The more accurate (but also heavily oversimplified) role of dopamine is that itâs released when we anticipate novelty or accomplishment, but it is not necessary associated with accomplishment itself. Dopamineâs role in motivating us to do hard things is vital, but it also motivates us to prioritize activities that feel productive, but arenât. This includes things like social media, email, news, etc.
Thereâs nothing inherently wrong with these activities but they often undermine calmâand thus productivityâby making us anxious and distracted, and by taking up a lot of time.
This is where âstimulation fastingâ comes in. Bailey talks about his attempt to remove unproductive tasks that made him feel busy but actually just led to increased anxiety. He gave a bunch of actionable advice, some of which inspired me to try this myself.
Recognizing the same problem in my own behavior, I experimented with this during much of December. They key tool was a little NFC reader called Brick which enables me to lock myself out of certain apps on my phone until I physically tap my phone to the Brick. It uses the same system as my iPhoneâs built-in ScreenTime feature, but with a physical lock that makes it much more effective.
Setting which apps to block was trickier than I was expecting. At first, I blocked the usual suspects like Instagram and Facebook (I also entirely deleted Twitter and Threads for reasons I may write about another time), but my habits changed quickly to habitually checking NetNewsWire, email, and playing games like Knotwords and Threes. So I adjusted the settings include these apps as well as Overcast (for podcasts). I really like Podcasts but I find myself too often turning on a podcast in order to procrastinate.
This experiment was largely successful. During December, I was able to write on this blog more, practice piano more, get longer stretches of productive work done, and avoid a lot of enraging news cycles about the upcoming Trump administration.
Looking ahead to 2025, I am going to take a more ambitious stimulation fast during the first 100 days of the Trump 2.0 administration. I think I can do it because I largely have the habits and systems in place from my December experiments. Iâm optimistic that I can personally grow from this period that I am certain will be terrible for our country and for our culture.
I believe this stimulation fast, in addition to all the other ideas from How to Calm Your Mind that Iâve written about previously, have a potential to really help during this very anxious time.
This is the third in a series of reflections I am writing on the ideas of How to Calm Your Mind by Chris Bailey.
This passage of How To Calm Your Mind particularly caught my attention:
One of my favorite things to ask someone when I meet them for the first time is this: What do you savor the most? In asking dozens of people this question, I have been surprised at how many people just donât have an answer.
[...]
This also holds true for the most successful people I know: the question leaves them dumbfounded and speechless, often for several seconds, as hey process the question and gather their thoughts.
I tried this out with a few friends and family and found the exact same result.
The book recommends identifying things I already enjoy, prioritize them, and dwell on the positives. Thatâs all fine and good, but the idea resonated me when applied slightly differently: Making an active effort to savor the activities I do regularly but often donât enjoy.
What comes to mind is my piano practices, which I try to do twice a day (once in the morning before work and again at night). I found this twice a day frequency to be necessary in order to make adequate progress in my skills, but itâs ambitious and most days I donât actually practice two times leading me to end the day feeling guilty and unproductive.
The solution Iâve tried is to bully myself into sitting down and practicing, including rigorously planning discrete practices and setting timers. This has worked somewhat, but with the downside of making my piano practices less fun and creative. In turn, that makes me less motivated to practice and makes it more difficult to force a practice the next day.
Over the last few weeks, I incorporated this idea of savoring into my piano practices and itâs made a huge difference.
I started intentionally appreciating as much as I can about these practice sessions: the feeling of the comfortable chair, the sound of the hammers hitting the strings, even the privilege of the opportunity to learn a creative skill deeply. It feels silly and artificial to do this, but typically after a few minutes I can observe a subtle but important shift in my mindset. The whole practice is more pleasant and captures my attention more fully. And when it comes to starting the second practice at the end of the day, itâs easier to get started because itâs a more pleasant activity.
In the past, Iâve chosen to focus on flow, and Iâve tried a bunch of timer apps and techniques to force myself into what can feel like a mythical state of mind. Finding flow is really hard in the same way that meditation is difficult: I donât really understand how to actively not do something.
I find savoring to be way easier because all I have to do is just take a moment and notice the pleasant things about an activity. Doing so makes me more engaged, which is largely the same goal I was striving for by pursuing flow.
The book outlines two main barriers to savoring, both of which I need to keep in mind:
Iâm guilty of both of these, which I knew made me less productive, but I had never quite considered that both could hinder my satisfaction with doing something. Conveniently enough, reducing distractions is something Iâll discuss in my next, and probably final, post about this book.
This is the second in a series of reflections I am writing on the ideas of How to Calm Your Mind by Chris Bailey.
I spend my days in the corporate world, so I certainly have felt and observed some amount of burnout. For me, it can feel like a very loaded and serious word to use, so I found the summary of burnout-related information in Chapter 3 of How to Calm Your Mind eye-opening.
It starts with the definition of burnout itself. The three components of burnout are:
Reading that precise definition of burnout, I was able to reflect on various periods where I felt some combination of these three factors. I also considered a recent episode at the end of November when I certainly was burned out but was too reluctant to use the B-word. When I think back on it, I think I didnât want to say I was burned out because I felt it was too hyperbolic or complain-y for my situation. But accurately determining the way I was feeling as burnout likely would have helped me better improve my situation faster.
The book outlines various fixes for burnout, but what stuck with me the most was the general-purpose advice:
Generally, if youâre feeling exhausted, focus on your workload. If youâre disengaged, invest in social relationships and find ways of connecting more deeply with your coworkers if you can. If youâre cynical, identify whether you have the resources you need to do your job, and again whether you can double down on relationships at work.
Thatâs advice I plan to commit to memory, so I can access it the next time I need it.
This is the first in a series of reflections I am writing on the ideas of How to Calm Your Mind by Chris Bailey.
In the first chapter, the book instructs the reader to reflect on this question: âHow do you determine whether a day of your life went well?â
There are many potential answers to this question, but when I reflect on the thoughts that go through my head as I fall asleep at night, the answer for me is clearly âhow much stuff I got doneâ.
The book calls this an âaccomplishment mindsetâ. On the surface, this didnât sound all that bad to me. I consider it a virtue to be productive and hard-working, and I generally enjoy trying out different productivity strategies and seeing how they can apply to my day. I am even developing some of these strategies into a productivity app.
But Bailey writes a perspective I hadnât fully considered before:
Productivity became the end I was seeking. Of course, productivity is a terrible end in and of itself: it should be thought of as a means to a more important end, such as having more free time, financial freedom, or more space to genuinely connect with others.
[...]
If you lose sight of this, as I did, you may also find that everything becomes workâsomething you need to do to get a result. Your to-do list becomes a diary of stuff you have to do, not things you get to do.
What feels mostly problematic about an accomplishment mindset for me is that it leads me to fill the extra time in my day with more stuff, which can make me anxious and burnout, which paradoxically makes me get less stuff done. And the cycle continues.
So, then, if I no longer want to assess a day by how much stuff I got done, what is the alternate? Hereâs the answer Iâm going to try out: âThe amount I was able to savor the dayâs activitiesâ.
My life is, thankfully, filled more with things that I enjoy than things I donât enjoy. And yet I easily lose sight of that when everything I enjoy is shoved into a to-do list. But with a set of small changes, I think it should be possible to measure my life by my presence and contentment.
I believe this is a more meaningful and worthwhile goal.
I just finished How To Calm Your Mind by Chris Bailey after hearing him on the Focused podcast. I picked up this book at the perfect time, a few weeks ago when I was dealing with some work burnout, the election results, and the general new yearâs reflection period.
The thesis of the book is that a productive mind is a calm mind. Itâs an idea I hadnât fully considered before, but one that immediately resonated with me and tied together many observations Iâve made about my personal productivity into a single framework.
Over the next couple weeks, my plan is to blog about some of these ideas as I experiment with some of the ideas in the book.
Topics may include:
To survive the period that lies ahead in America, I think itâs valuable to reflect and draw some âlines in the sandâ. Lines that when crossed disqualify someone from my compassion and cooperation.
So here are my lines in the sand.
You may choose yours differently, but these are mine and I will hold them unwaveringly for the rest of my life.
I am slowly but steadily getting Habituate to a shippable state. Last week, I got the account management system working with an app architecture that suits the app well. Also made a bunch of visual iterations to the home and settings screens.
Still on my todo list for these screen:
At WWDC 2019, I met the developers of Bear, which I consider to be one of the best iOS/macOS apps ever made. In my brief chat with them, I reflected on my struggles finding time to work on personal project apps. I havenât forgotten the insight they gave me:
You can make progress with just 1 hour a week. But you canât make progress with 0 hours a week.
It may sound obvious, but this has suck with me. I can build on a personal project by making incremental progress over time. I just needed to find an hour a week!
And yet, despite scheduling many blocks in my schedule to work on personal projects, here we are 4 years later without much to show for myself. After some reflection, I believe my issue is that I donât structure this time to actually finish anything in those working sessions. If I only have a 20 minute block of time, then I need a task that I can conceivably finish in 20 minutes, otherwise Iâll feel unproductive and time-constrained.
My proposed solution to this is inspired from my day job. At work, the role of a product manager, designer, and engineer are different people. I do all these jobs for my personal projects, but it is helpful to think of these jobs separately. Making a product decision, designing a solution, and writing code can be considered separate tasks. Lumping all these tasks together while writing code is so tempting because it feels like Iâm moving faster, but doing so makes it harder to break projects into shorter tasks and make progress with short blocks of time.
This week I tried this out. In my lunch breaks, I spent 20 minutes a day working on the sign-in/sign-up screens in Habituate. One day, I decided on a authentication service and the requirements for account management, the next day I mocked up the sign in screens and account settings in Figma, and the third day I typed up those screens in code and hooked it up to the authentication service. Just ~20 minutes day, less than an hour of work. But at the end of the week, I now have the full feature more-or-less complete. And next week I can move on to something else.
It will still take a long time to finish, but it feels very good to be moving forward.
Downstage (formerly Learn Your Lines) is available as a TestFlight beta, to use it:
I very much would like feedback and bug reports. You can submit that feedback within the TestFlight app.
Happy Memorizing.
In the dark days of the pandemic, I read Walter Isaacson’s biography of Benjamin Franklin. Of the many quotes Franklin is famous for, one stuck out to me personally:
To cease to think creatively is to cease to live.
I think I am not alone in my personal struggle to remain creative over the past few years. What I’ve learned is that thinking creatively is hard work. It takes practice and perseverance to make creativity part of your life, and it’s frankly easier to just… not.
But that’s not the kind of life I want to live.
Creativity is something I’m hoping to reinvigorate in various parts of my life, but the area that is relevant to this blog is designing and creating indie apps. I am currently working on two apps in my free time:
Downstage (formerly Learn Your Lines) my line learner app.
Habituate, a routine timer app. (Still working on how to explain this one)
My goal is that working on these apps will instill a creative and entrepreneurial vigor in my life. Initially, I care more about enriching my life than making a bunch of money on these apps… but I’ll admit that making Learn Your Lines for many years and never charging for it was probably not my best decision.
This blog can play a key part of my personal goal to be more creative. My hope is to narrate my design process on this website, using writing as a tool to think more clearly and rigorously.
Much more to come.
One of my favorite new features of iPadOS 14 is Scribble, which allows me to write directly onto system text inputs using an Apple Pencil. One cool feature of Scribble I just discovered is that it uses the same Text Replacements you can configure for the software keyboard. You can create a Text Replacement in Settings > General > Keyboards > Text Replacement
.
All of my Text Replacements are available in Scribble!
This is also a great way to add custom non-dictionary words (like names) to make handwriting recognition more accurate.
Looks great, with a clever API similar to watch complications. Curious to see how much functionality is possible in a widget (or allowed by App Review).
Crazy that pinning widgets to the homescreen is not available in iPadOS. I would be very surprised if this is not coming in a future beta.
Itâs a shame that YouTube wonât support this.
Cycling directions are the only reason I have Google Maps installed on my phone. This new feature in Apple Maps surpasses Googleâs implementation with elevation information and annotations on the route options like âless busyâ and âfastestâ.
Apple pitched this primarily as a quick way to collect payments for things like parking meters and scooters, but users can also access an App Clip on the web.
I wonder if App Review would allow an App Clip that serves as a demo of an app. It would be awesome to make an App Clip of the main memorization modes in Learn Your Lines for users to try out from the promo website.
Something to look into.
Handwriting recognition in all standard text inputs is something Iâve wanted ever since I got an Apple Pencil, so Iâm very excited to try this out. Curious to see if there are new APIs for handwriting recognition.
I have no faith that this will work reliably, but it would be great if it did.
I did not see this coming, but so far Iâm enthusiastic about the redesign. Especially as more apps share UI code between iOS and macOS, it is a huge waste of time for developers to make arbitrary visual differences to the UI on the Mac.
Thereâs a lot to consider about the details of the actual implementation here, so the jury is still out on this one.
Very interesting on an academic level, but Iâll be much more excited when they announce new hardware. Iâm unreasonably curious about what they will call the new CPUs when the products are launched, since âApple Siliconâ must be a placeholder.
â
Overall, this was a very enjoyable set of announcements sparking many ideas for things to incorporate in my existing projects. And while I would have loved to be there in person, the pre-recorded presentation was very entertaining and excellent.
The ever-brilliant Kara Swisher recently began referring to Mark Zuckerberg as the âSusan Collins of the Internetâ in response to Zuckerbergâs inaction about Trumpâs clearly dangerous posts on Facebook. I love this framing, and hereâs why:
Susan Collins, the senator of Maine since 1996 (the year I was born), prides herself on being an independent, sober thinker within a hot-tempered Republican Party. Her record, though, paints an entirely different picture.
In 2016, she declared she would not be voting for Donald Trump, and yet over the past 4 years she has continually empowered him at the most critical moments. She personally opposed tenents of the Republican tax bill, yet voted for it anyway. She derides the denigration of women, but voted to confirm Bret Kavanagh. She has come to occupy a fantasy moral highground by voicing strong personal objections yet voting against her own positions when politically inconvenient. For this reason, Susan Collins generally polls as the least popular member of the Senate.
Which is what makes Kara Swisherâs comparison to Mark Zuckerberg so perfect.
On Saturday, discussing Trumpâs comments in a Facebook post, Zuckerberg writes: âPersonally, I have a visceral negative reaction to this kind of divisive and inflammatory rhetoric.â 24 hours later, according to a report in Axios, Trump called Mark Zuckerberg on the phone. Faced with an incredible opportunity for Zuckerberg to use his clout with the Presdient, he âdidnât make any specific requestsâ.
Itâs important to call out that Zuckerberg is in complete control over Facebook and, uniquely among any other CEO, cannot be ousted by the Board of Directors or investors. This makes his inaction so utterly dissapointing. Zuckerberg has abdicated all responsibility of leadership despite having the privilege, opportunity, and personal interest to do something. For this reason, he is just as worthy of my disrespect as Americaâs most unpopular senator.
This morning, I spent a few hours researching Section 230 of the Communications Decency Act, considered by many to be the foundational law on internet speech and the center of many political squabbles. I did this to clarify my thinking on the topic and as a prerequisite to truly assessing the many proposals to change the law.
Here is the opening from The Vergeâs explainer of the law:
Section 230 of the Communications Decency Act, which was passed in 1996, says an âinteractive computer serviceâ canât be treated as the publisher or speaker of third-party content. This protects websites from lawsuits if a user posts something illegal.
[…]
Sen. Ron Wyden (D-OR) and Rep. Chris Cox (R-CA) crafted Section 230 so website owners could moderate sites without worrying about legal liability.
Writing in my notes, I summarized the above statements like this:
Thinking it through, these two bullet points confused me. Why did Ron Wydon and Chris Cox encourage moderation on the internet by writing a law that removes an incentive to do so?
To get clarity on this question, I continued reading explanations of the law. I found this piece by Ben Thompson to be particularly helpful because it describes the legal landscape for internet speech before The Communications Decency Act was signed into law.
In 1992, CompuServe was sued for defamatory remarks found on its forums. The judge ruled that since CompuServe had no editorial control over the forum content, it was not liable for the content similar to how a public library is not liable for the contents of a book it distributes.
In 1996, Prodigy was sued for libel in content on its own internet forums. This time, the judge ruled that Prodigy was liable for its forum content because the forums had moderators and used content screening software. The court decision considered Prodigyâs content moderation legally equivalent to the editorial control that a newspaper has as a publisher. Prodigy was forced to pay $200 million and a new court precedent was established: moderating internet content in any way makes an internet service liable for all its user-generated content.
The combination of these two court decisions provided no middle ground between a distributor (CompuServe with no moderation) and a publisher (Prodigy with some moderation). To create a video-sharing website like YouTube in 1996, your options were to avoid moderation entirely (not desirable for obvious reasons) or be legally liable for every video (which would flood a service even a fraction the size of YouTube with lawsuits).
In response to this dilemma, Wyden and Cox wrote Section 230 to specifically allow any internet service to moderate content based on any standard without assuming liability of that content.
With this information, the Electronic Frontier Foundationâs explanation of the law made much more sense to me: > [Section 230] is one of the most valuable tools for protecting freedom of expression and innovation on the internet. […] This comes as somewhat of a surprise, since the original purpose of the legislation was to restrict free speech on the Intenet. Section 230 says that… online intermediates that host or republish speech are protected against a range of laws that might otherwise be used to hold them legally responsible for what others say and do.
The law does not disincentivize internet services from moderation, as I originally thought. Instead, it allows services to moderate content in the first place, enabling more content posted on the internet, and thus more speech expressed in the world.
â
This isnât very complicated conceptually, but it took an entire morning for me to clearly understand. Because of this, Iâm not surprised that the law is frequently misinterpreted by both Democrats and Republicans, including the Presidentâs recent executive order which chaotically (and unconstitutionally) attempts to repeal the law.
By better understanding this issue, I hope I can more effectively participate in the many debates surrounding this issue. The conversation about internet speech is only getting started, so now is the time to prepare.
Version 5.5.1 of iA Writer adjusted its Micro.blog integration flow. They improved it in all the ways I proposed in my post last week.
This is great news because I implemented a similar add account flow in MicroPublisher this morning, and this is a nice affirmation of my design decisions.
I keep going back and forth on this: should the name of this app be MicroPublisher or Micropublisher?
I originally called the app capital-p MicroPublisher, because Iâm a Pascal Case kind of person. As a Swift programmer, this is the variable name I would give for the app.
Additionally, the word âPublishâ is a bit easier to parse at a glance which could make it ever so slightly more recognizable in a list of apps or search results.
Yet I canât escape the fact that the web standard is called Micropub, with a lowercase âpâ. I always notice when people mess up the arbitrary capitalization of words like Xcode, iPhone, and macOS. Is naming the app MicroPublisher akin to naming an Xcode extension âxCoderâ?
I realize that Iâm surely overthinking it. Which is why Iâm going ahead with my preferred name: MicroPublisher. But let the record show that the name wasnât chosen without consideration.
This week, IA Writer added native publishing to Micropub endpoints. This is quite relevant to my interests because I host my blog on Micro.blog, I use IA Writer to write my blog posts, and Iâm currently working on an app to publish to Micropub endpoints from the iOS system share sheet. So I was excited to try it out this morning.
In summary, despite some initial confusion authenticating and some nitpicks (discussed below), I like their implementation. Iâm planning to steal some of their ideas for Micropublisher (which Iâm making great progress on and will write more about soon).
This is the prompt IA Writer shows when you add a Micropub account:
âURL… of what?â, I asked. One feature of Micro.blog is that your blog content has 2 URLs:
username.micro.blog
. On top of that, I have a custom domain name which, as far as I understand, is equivalent to this URL.micro.blog/username
.I first tried typing in thecope.net
: âAccess deniedâ
Next I tried https://micro.blog/cope
: âIndieAuth Not Foundâ
Maybe just micro.blog
?: âAccess deniedâ
Next I created a manual authentication token for IA Writer so I could enter it manually, but I still needed to type in a URL, so the issue remained.
Finally, I tried cope.micro.blog
: It worked. I was sent to confirm the authorization on Micro.blog and came back to IA Writer with the account successfully configured.
My trouble with the URL wasnât a huge problem, but it was a bit of added friction to the experience. What I would change about IA Writerâs design is to provide separate account types for âMicro.blogâ and âMicropubâ. The two options would do exactly the same thing, but when the user selects âMicro.blogâ the modal could be customized in 3 minor ways:
username.micro.blog
.It would also be great to see Micro.blog as an equal companion to Ghost, Medium, and WordPress (Manton Reese and Daniel Jalkut discussed this topic on this weekâs Core Intuition, and I think this is a reasonable solution to the issue that would be easy to implement for IA Writer).
It was possible that using the Micropub integration in IA Writer would discourage me from finishing Micropublisher because the lack of this feature is what sparked the idea for the app in the first place. But Iâm actually more motivated than ever about this project. I can take all my nitpicks of IA Writerâs implementation to improve the design of Micropublisher.
Now back to work.
Many bloggers who write on iOS use custom automation scripts and shortcuts to publish to their blogs. This can be a fun automation project for programmers, but not a viable or elegant solution for everyone else.
After playing with the Micropub API on Monday, I began working on an app to post to a Micropub endpoint with a system share sheet action. If everything goes according to plan, then this post will be published from IA Writerâs share sheet using this app.
(Update after publishing: everything went according to plan).
My working title for the app is MicroPublisher. Iâm not sure if Iâll ever polish MicroPublisher for the App Store, but thatâs my current goal. At the very least, Iâm using this project to learn SwiftUI (which Iâll write about later because itâs really awesome).
A lot of work remains on this project, which will give me a lot to write about on this blog (which will give me more ways to test the app. A virtuous cycle).
Last night (while waiting to watch the season 3 finale of Westworld), I wrote a Python script to post to my blog from iOS.
Many have done this before, so I found many examples online to get me started. What surprised me was just how simple the Micropub API makes it to post.
Hereâs the basic example in Python:
import requests
response = requests.post(
url=endpoint_url,
headers={
"Authorization": âBearer â + api_token,
"Content-Type": "application/x-www-form-urlencoded; charset=utf-8",
},
data={
"h": "entry",
"content": text_of_post
},
)
And in Swift (if youâll allow the Alamofire dependency):
import Alamofire
AF.request(
endpointURL,
method: .post,
parameters: [
"h": "entry",
"content": textOfPost
],
encoding: URLEncoding.queryString,
headers: [
"Authorization": "Bearer \(apiToken)"
]
)
Something so simple but powerful promotes creativity, and it gives me The Itch to make something.
Is there an iOS app publish to a Micropub endpoint from a share extension? A search for âmicropubâ on the App Store would indicate ânoâ. But how difficult would it be to make this? Afterall, the difficult code is already written above.
Something for me to think about…
Learn Your Lines 4.0.4 fixes an issue where Read Mode would pause after reading a line.
Learn Your Lines 4.0.3 adds hover states to buttons when using an external pointer on iPad.
Xcode 11.4 was released last week bringing new APIs to complement the new (and very delightful) pointer support in iPadOS 13.4.
I spent the afternoon adding pointer support to my app and in the process wrote down what I learned as a complement to the official documentation.
The new mouse cursor on iOS adapts based on the content underneath it. When the pointer hits an app icon on the home screen, for example, it morphs into the shape of the app icon. This behavior is implemented by default on UIButton
, UIBarButtonItem
, and UISegmentedControl
.
Most apps will need to add interactivity in additional places. The new UIPointerInteraction
APIs are how you do it:
let pointerInteraction = UIPointerInteraction(delegate: nil)
view.addInteraction(pointerInteraction)
Adding this code to any UIView
will add the default pointer interaction to any view, but you can customize the interaction further by implementing providing a UIPointerInteractionDelegate
to the interaction.
Pointer interactivity is comprised of two different types of customizations: effects and shapes. Both these types are outlined below.
A UIPointerEffect
describes the interaction between the pointer and the view underneath it. The API provides 3 types of effects:
With the lift effect, the pointer will morph behind the view, animate it with parallax effects, and add a drop shadow.
For views with a height or width larger than 175, the pointer will not morph behind the view and remain visible.
func pointerInteraction(_ interaction: UIPointerInteraction, styleFor region: UIPointerRegion) -> UIPointerStyle? {
var pointerStyle: UIPointerStyle? = nil
if let interactionView = interaction.view {
let targetedPreview = UITargetedPreview(view: interactionView)
pointerStyle = UIPointerStyle(effect: UIPointerEffect.lift(targetedPreview))
}
return pointerStyle
}
The highlight effect is very similar to lift, except does not add a drop shadow. This can be useful when you are interacting with a view that already has a drop shadow, or shadows don’t look good visually in your app.
func pointerInteraction(_ interaction: UIPointerInteraction, styleFor region: UIPointerRegion) -> UIPointerStyle? {
var pointerStyle: UIPointerStyle? = nil
if let interactionView = interaction.view {
let targetedPreview = UITargetedPreview(view: interactionView)
pointerStyle = UIPointerStyle(effect: UIPointerEffect.highlight(targetedPreview))
}
return pointerStyle
}
You can use the hover effect to customize the interaction more specifically.
func pointerInteraction(_ interaction: UIPointerInteraction, styleFor region: UIPointerRegion) -> UIPointerStyle? {
var pointerStyle: UIPointerStyle? = nil
if let interactionView = interaction.view {
let targetedPreview = UITargetedPreview(view: interactionView)
let hoverEffect = UIPointerEffect.hover(
targetedPreview,
preferredTintMode: .overlay, // or .underlay
prefersShadow: false,
prefersScaledContent: true
)
pointerStyle = UIPointerStyle(effect: hoverEffect)
}
return pointerStyle
}
You can configure the hover effect with the following properties:
preferredTintMode
: determines if the color of the view should be shifted in the parallax effect.prefersShadow
: determines if a drop shadow should be added.prefersScaledContent
: determines if the view should be scaled up.You may want to use the hover effect to disable some default effects when you are implementing custom view transformations when the pointer interacts with a view. These view customizations can be implemented in the UIPointerInteractionDelegate
methods pointerInteraction(:willEnter:animator)
and pointerInteraction(:willExit:animator)
.
When the pointer hovers over a view, it can also change shape to communicate what the pointer will do when clicked.
By default, the pointer will become an I-beam when hovering over editable text.
You can define your own custom shapes by creating a UIPointerShape
with a custom bézier path to UIPointerShape
.
func pointerInteraction(_ interaction: UIPointerInteraction, styleFor region: UIPointerRegion) -> UIPointerStyle? {
var pointerStyle: UIPointerStyle? = nil
if let interactionView = interaction.view {
let targetedPreview = UITargetedPreview(view: interactionView)
let shape = UIPointerShape.path(gearPath)
pointerStyle = UIPointerStyle(shape: shape)
}
return pointerStyle
}
To create bezier paths for complex shapes, I recommend Paintcode which is a great Mac app which converts vector shapes into Swift or Objective-c UIBezierPath
code.
And thatâs it. Iâve been having a lot of fun playing with these APIs in Learn Your Lines, and plan to release the changes in the next few days.
In the latest version of Learn Your Lines, I fixed a bug where back buttons were sometimes not visible.